diff --git a/__tests__/__snapshots__/wrap.test.js.snap b/__tests__/__snapshots__/wrap.test.js.snap
index e98c5ab..46e539e 100644
--- a/__tests__/__snapshots__/wrap.test.js.snap
+++ b/__tests__/__snapshots__/wrap.test.js.snap
@@ -1,3 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
exports[`wrap should pass all properties to wrapped component and add styles to the view 1`] = `
+ }
+/>
`;
diff --git a/__tests__/fixtures/style-inherit.js b/__tests__/fixtures/style-inherit.js
index 9f181e7..4d58fd3 100644
--- a/__tests__/fixtures/style-inherit.js
+++ b/__tests__/fixtures/style-inherit.js
@@ -1 +1 @@
-module.exports = {".test view text.hello&inherited":{"fontSize":14},".test view text.hello":{"color":"black"},".test view.direct text.hello:not(.direct)&inherited":{"fontSize":14},".test view.direct>text.hello:not(.direct)":{"color":"blue"},".test view.direct>text.hello":{"fontSize":16},"text&inherited":{"fontSize":14},"text":{"color":"red"},"scrollview":{"padding":10},"*":{"margin":5}}
\ No newline at end of file
+module.exports = require('react-native').StyleSheet.create({".test view text.hello&inherited":{"fontSize":14},".test view text.hello":{"color":"black"},".test view.direct text.hello:not(.direct)&inherited":{"fontSize":14},".test view.direct>text.hello:not(.direct)":{"color":"blue"},".test view.direct>text.hello":{"fontSize":16},"text&inherited":{"fontSize":14},"text":{"color":"red"},"scrollview":{"padding":10},"*":{"margin":5}});
\ No newline at end of file
diff --git a/__tests__/fixtures/style-test-literal.js b/__tests__/fixtures/style-test-literal.js
index 6e7fcb7..ac5e5ac 100644
--- a/__tests__/fixtures/style-test-literal.js
+++ b/__tests__/fixtures/style-test-literal.js
@@ -1 +1 @@
-module.exports = {"maincontainer":{"flex":1,"justifyContent":"center","alignItems":"center","backgroundColor":"#F5FCFF"},"rootcontainer":{"flex":1,"fontSize":18}}
\ No newline at end of file
+module.exports = require('react-native').StyleSheet.create({"maincontainer":{"flex":1,"justifyContent":"center","alignItems":"center","backgroundColor":"#F5FCFF"},"rootcontainer":{"flex":1,"fontSize":18}});
\ No newline at end of file
diff --git a/__tests__/rnc.test.js b/__tests__/rnc.test.js
index a52a985..8c7e079 100644
--- a/__tests__/rnc.test.js
+++ b/__tests__/rnc.test.js
@@ -7,12 +7,12 @@ global.Promise = require.requireActual('promise');
describe('React Native CSS Command-line', ()=> {
it("should parse CSS", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style.css', './__tests__/fixtures/style.js', false, true);
+ let data = await css.parse({input: './__tests__/fixtures/style.css'});
expect(data).toEqual({main: {backgroundColor: '#000'}});
});
it("shoud parse SCSS", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style.scss', './__tests__/fixtures/stylescss.js', false, false);
+ let data = await css.parse({input: './__tests__/fixtures/style.scss'});
expect(data).toEqual({
description: {
flex: 102,
@@ -33,7 +33,7 @@ describe('React Native CSS Command-line', ()=> {
});
it("Parse SCSS error", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style-20.scss', './__tests__/fixtures/stylescss-20.js', false, false);
+ let data = await css.parse({input: './__tests__/fixtures/style-20.scss'});
expect(data).toEqual({
maincontainer: {
flex: 1,
@@ -46,7 +46,7 @@ describe('React Native CSS Command-line', ()=> {
});
it("Parse SCSS error", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style-dorthwein.scss', './__tests__/fixtures/stylescss-dorthwein.js', false, false);
+ let data = await css.parse({input: './__tests__/fixtures/style-dorthwein.scss'});
expect(data).toEqual({
center: {
alignItems: 'center',
@@ -58,12 +58,12 @@ describe('React Native CSS Command-line', ()=> {
});
it("Parse CSS and ignore unsupported property", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style-unsupported.scss', './__tests__/fixtures/style-unsupported.js', false, false);
+ let data = await css.parse({input: './__tests__/fixtures/style-unsupported.scss'});
expect(data).toEqual({container: {background: 'white'}});
});
it("Parse CSS and turn properties into numbers", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style-number.scss', './__tests__/fixtures/style-number.js', false, false);
+ let data = await css.parse({input: './__tests__/fixtures/style-number.scss'});
expect(data).toEqual({
text: {
fontSize: 12,
@@ -73,7 +73,7 @@ describe('React Native CSS Command-line', ()=> {
});
it("Regression test for issue #26", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style-test.css', './__tests__/fixtures/style-test.js', false, false);
+ let data = await css.parse({input: './__tests__/fixtures/style-test.css'});
expect(data).toEqual({
"row": {
"top": 50,
@@ -91,14 +91,18 @@ describe('React Native CSS Command-line', ()=> {
});
it("Argument --literal generates a javascript literal object", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style-20.scss', './__tests__/fixtures/style-test-literal.js', false, true);
+ await css.parse({
+ input: './__tests__/fixtures/style-20.scss',
+ output: './__tests__/fixtures/style-test-literal.js', //actually tests the output
+ objectLiteral: true
+ });
var styles = require('./fixtures/style-test-literal.js');
expect(styles.maincontainer.backgroundColor).toEqual("#F5FCFF");
});
it("Parse CSS and expand shorthand properties", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style-expand.css', './__tests__/fixtures/style-expand.js', false, false);
+ let data = await css.parse({input: './__tests__/fixtures/style-expand.css'});
expect(data).toEqual({
"container": {
"paddingTop": 10,
@@ -142,8 +146,8 @@ describe('React Native CSS Command-line', ()=> {
});
});
- it("Test inheritance CSS", async ()=> {
- let data = await css.parse('./__tests__/fixtures/style-inherit.css', './__tests__/fixtures/style-inherit.js', false, true, true);
+ it("Test inheritance CSS", ()=> {
+ let data = css.parse({input: './__tests__/fixtures/style-inherit.css', useInheritance: true});
register(data);
expect(matchRules([{e: 'view', c: ['test']}, {e: 'view', c: ['test']}, {
diff --git a/__tests__/wrap.test.js b/__tests__/wrap.test.js
index a3724ba..206f664 100644
--- a/__tests__/wrap.test.js
+++ b/__tests__/wrap.test.js
@@ -14,7 +14,10 @@ global.Promise = require.requireActual('promise');
describe('wrap', ()=> {
it('should pass all properties to wrapped component and add styles to the view', async ()=> {
//create the style object
- let styles = await css.parse('./__tests__/fixtures/style-inherit.css', null, false, true, true);
+ let styles = css.parse({
+ input: './__tests__/fixtures/style-inherit.css',
+ useInheritance: true
+ });
//register the global sheet
register(styles);
diff --git a/babel.js b/babel.js
new file mode 100644
index 0000000..f0408b9
--- /dev/null
+++ b/babel.js
@@ -0,0 +1,2 @@
+require('babel-polyfill')
+module.exports = require('./build/babelTransform').default;
diff --git a/bin/react-native-css b/bin/react-native-css
index 49cb41c..bcd24d4 100755
--- a/bin/react-native-css
+++ b/bin/react-native-css
@@ -21,7 +21,7 @@ if(inputOutput) {
var input = path.resolve(process.cwd(), inputArgs);
var output = path.resolve(process.cwd(), outputArgs);
- css.parse(input, output, prettyPrint, literalObject, useInheritance);
+ css.parse({input:input, output:output, prettyPrint:prettyPrint, literalObject:literalObject, useInheritance:useInheritance});
if(watch) {
console.log('Watching for changes on:'.green, inputArgs);
@@ -31,7 +31,7 @@ if(inputOutput) {
ignored: /[\/\\]\./, persistent: true
}).on('change', function(path) {
console.log('File', inputArgs, 'has been changed'.green);
- css.parse(input, output, prettyPrint, literalObject, useInheritance);
+ css.parse({input:input, output:output, prettyPrint:prettyPrint, literalObject:literalObject, useInheritance:useInheritance});
});
}
}else if(help ) {
diff --git a/build/babelTransform.js b/build/babelTransform.js
new file mode 100644
index 0000000..6c995ac
--- /dev/null
+++ b/build/babelTransform.js
@@ -0,0 +1,44 @@
+Object.defineProperty(exports,"__esModule",{value:true});exports.default=
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function(_ref){var t=_ref.types;
+return{
+visitor:{
+ImportDeclaration:function ImportDeclaration(transformPath,_ref2){var file=_ref2.file;
+var resolvePath=transformPath.node.source.value;
+if(resolvePath.startsWith('css!')){
+resolvePath=resolvePath.substr(4);
+var name=resolvePath.replace(/\.\.\/|\.\//g,'').replace(/\//g,'_').split('.')[0];
+var absolutePath=_path2.default.resolve(_path2.default.dirname(file.opts.filename),resolvePath),
+relativePath=_path2.default.dirname(absolutePath)+'/_transformed/'+name+'.js';
+startTransform(absolutePath,_path2.default.resolve(relativePath));
+
+var expression=t.callExpression(t.memberExpression(t.callExpression(t.identifier('require'),[t.stringLiteral('react-native-css')]),t.identifier('register')),[t.callExpression(t.identifier('require'),[_path2.default.resolve(relativePath)])]);
+transformPath.replaceWith(expression);
+}
+}}};
+
+
+};var _index=require('./index');var _index2=_interopRequireDefault(_index);var _path=require('path');var _path2=_interopRequireDefault(_path);var _child_process=require('child_process');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var css=new _index2.default();function runWatcher(input,output){(0,_child_process.spawn)('node',['./watcher.js',input,output],{detached:true,cwd:__dirname});}function startTransform(input,output){css.parse({input:input,output:output,useInheritance:true});if(process.env.BABEL_ENV==='development'){runWatcher(input,output);}return true;}
\ No newline at end of file
diff --git a/build/client.js b/build/client.js
new file mode 100644
index 0000000..48960c5
--- /dev/null
+++ b/build/client.js
@@ -0,0 +1,80 @@
+var _reactNative=require("react-native");var _reactNative2=_interopRequireDefault(_reactNative);
+var _css=require("./css");var _css2=_interopRequireDefault(_css);
+var _wrap=require("./wrap");var _wrap2=_interopRequireDefault(_wrap);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
+
+
+var componentsToWrap=["ActivityIndicator",
+"ActivityIndicatorIOS",
+"ART",
+"DatePickerIOS",
+"DrawerLayoutAndroid",
+"Image",
+"ImageEditor",
+"ImageStore",
+"KeyboardAvoidingView",
+"ListView",
+"MapView",
+"Modal",
+"Navigator",
+"NavigatorIOS",
+"Picker",
+"PickerIOS",
+"ProgressBarAndroid",
+"ProgressViewIOS",
+"ScrollView",
+"SegmentedControlIOS",
+"Slider",
+"SliderIOS",
+"SnapshotViewIOS",
+"Switch",
+"RecyclerViewBackedScrollView",
+"RefreshControl",
+"StatusBar",
+"SwipeableListView",
+"SwitchAndroid",
+"SwitchIOS",
+"TabBarIOS",
+"Text",
+"TextInput",
+"ToastAndroid",
+"ToolbarAndroid",
+"Touchable",
+"TouchableHighlight",
+"TouchableNativeFeedback",
+"TouchableOpacity",
+"TouchableWithoutFeedback",
+"View",
+"ViewPagerAndroid",
+"WebView"];
+
+
+var StyledComponents={};
+var wrappedComponents={};
+
+componentsToWrap.forEach(function(name){
+Object.defineProperty(StyledComponents,name,{
+get:function get(){
+return wrappedComponents[name]||(wrappedComponents[name]=(0,_wrap2.default)(name,_reactNative2.default[name]));
+}});
+
+});
+
+
+
+Object.keys(_reactNative2.default).forEach(function(name){
+if(componentsToWrap.indexOf(name)===-1){
+Object.defineProperty(StyledComponents,name,{
+get:function get(){
+return _reactNative2.default[name];
+}});
+
+}
+});
+
+
+StyledComponents.unregister=_css.unregister;
+StyledComponents.register=_css.register;
+StyledComponents.css=_css2.default;
+StyledComponents.wrap=_wrap2.default;
+
+module.exports=StyledComponents;
\ No newline at end of file
diff --git a/build/css.js b/build/css.js
new file mode 100644
index 0000000..bb4478d
--- /dev/null
+++ b/build/css.js
@@ -0,0 +1,256 @@
+Object.defineProperty(exports,"__esModule",{value:true});exports.matchingRules=exports.unregister=exports.register=undefined;var _extends=Object.assign||function(target){for(var i=1;i\s*/g,">").replace(/\s+/g," ").split(" ").forEach(function(part){
+var immediates=part.split(">");
+immediates.forEach(function(immediate,i){
+var pseudo=immediate.split(":"),
+normal=pseudo.shift(),
+classes=normal.split(".").filter(function(a){return a;}),
+element=normal.charAt(0)==="."?"*":classes.shift();
+
+pseudo=pseudo.map(function(pseudo){return pseudos.find(function(test){return test.regex.exec(pseudo);});}).filter(function(test){return test;}).map(function(test){
+var matches=test.regex.exec(pseudo);
+if(matches){
+return test.match.bind(null,matches);
+}
+}).filter(function(ps){return ps;});
+
+path.push({
+e:element,
+c:classes,
+ps:pseudo.length&&pseudo,
+i:immediates.length>0&&i!=immediates.length-1});
+
+});
+});
+path=path.reverse();
+var first=path.shift();
+
+var specificity=0;
+
+specificity+=first.c.length*10;
+if(path.length>0&&path.i){
+specificity+=5;
+}
+if(first.e!=="*"){
+specificity++;
+}
+
+path.forEach(function(a){
+specificity+=a.c.length;
+});
+
+if(!rules[first.e]){
+rules[first.e]=[];
+}
+rules[first.e].push(_extends({},first,{a:path,s:specificity,o:o,k:key}));
+});
+return rules;
+}
+
+
+
+
+
+
+
+
+function elementMatches(target,matching){
+if(target.e!==matching.e&&matching.e!=="*"){
+return false;
+}
+if(matching.c&&!matching.c.every(function(className){return target.c&&target.c.indexOf(className)>-1;})){
+return false;
+}
+return!matching.ps||matching.ps.every(function(match){return match(target);});
+}
+
+
+
+
+
+
+function matchingRules(path,key){
+try{
+if(!key){
+key=JSON.stringify(path);
+}
+if(styleCache[key]){
+return styleCache[key];
+}
+
+path=path.slice(0).reverse();
+if(!path[0]){
+return styleCache[key]=null;
+}
+var element=path[0].e;
+
+
+
+var starting=(ruleKeys[element]||[]).concat(ruleKeys["*"]||[]);
+var matchingStyles=starting.filter(function(rule){
+if(!elementMatches(path[0],rule)){
+return;
+}
+var index=1,lastRelative=-1;
+return rule.a.every(function(ancestor,i){
+main:for(;index-1){
+
+index++;
+var ancestors=rule.a.slice(lastRelative,i-1),
+directAncestor=ancestor.shift();
+for(;index-1){
+sheets.splice(index,1);
+}
+});
+flattenSheets();
+}exports.default=
+
+css;exports.
+register=register;exports.unregister=unregister;exports.matchingRules=matchingRules;
\ No newline at end of file
diff --git a/build/index.js b/build/index.js
index b8312ce..8dd24d7 100644
--- a/build/index.js
+++ b/build/index.js
@@ -3,39 +3,35 @@ var _toCamelCase=require('to-camel-case');var _toCamelCase2=_interopRequireDefau
var _utils=require('./utils');var _utils2=_interopRequireDefault(_utils);
var _inheritance=require('./inheritance');var _inheritance2=_interopRequireDefault(_inheritance);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var
-ReactNativeCss=function(){function ReactNativeCss(){_classCallCheck(this,ReactNativeCss);}_createClass(ReactNativeCss,[{key:'parse',value:function parse(
-
-input){var output=arguments.length<=1||arguments[1]===undefined?'./style.js':arguments[1];var prettyPrint=arguments.length<=2||arguments[2]===undefined?false:arguments[2];var _this=this;var literalObject=arguments.length<=3||arguments[3]===undefined?false:arguments[3];var useInheritance=arguments.length<=4||arguments[4]===undefined?false:arguments[4];var _require$renderSync,css,styleSheet;return regeneratorRuntime.async(function parse$(_context){while(1){switch(_context.prev=_context.next){case 0:if(!
-_utils2.default.contains(input,/scss/)){_context.next=8;break;}_require$renderSync=
+ReactNativeCss=function(){function ReactNativeCss(){_classCallCheck(this,ReactNativeCss);}_createClass(ReactNativeCss,[{key:'parse',value:function parse(_ref)
+{var input=_ref.input,output=_ref.output,_ref$prettyPrint=_ref.prettyPrint,prettyPrint=_ref$prettyPrint===undefined?false:_ref$prettyPrint,_ref$literalObject=_ref.literalObject,literalObject=_ref$literalObject===undefined?false:_ref$literalObject,_ref$useInheritance=_ref.useInheritance,useInheritance=_ref$useInheritance===undefined?false:_ref$useInheritance;
+if(!input){
+throw new Error('An input file is required.');
+}
+var data=void 0;
+if(_utils2.default.contains(input,/scss/)){var _require$renderSync=
require('node-sass').renderSync({
file:input,
-outputStyle:'compressed'});css=_require$renderSync.css;
-
+outputStyle:'compressed'}),css=_require$renderSync.css;
-styleSheet=this.toJSS(css.toString(),useInheritance);
-if(output)
-_utils2.default.outputReactFriendlyStyle(styleSheet,output,prettyPrint,literalObject);return _context.abrupt('return',
-styleSheet);case 8:_context.next=10;return regeneratorRuntime.awrap(
-
-
-new Promise(function(resolve,reject){return _utils2.default.readFile(input,function(err,data){
-if(err){
-return reject(err);
+data=css.toString();
+}else{
+data=_utils2.default.readFile(input);
}
-var styleSheet=_this.toJSS(data,useInheritance);
-if(output)
-_utils2.default.outputReactFriendlyStyle(styleSheet,output,prettyPrint,literalObject);
-resolve(styleSheet);
-});}));case 10:return _context.abrupt('return',_context.sent);case 11:case'end':return _context.stop();}}},null,this);}},{key:'toJSS',value:function toJSS(
-
+var styleSheet=this.toJSS(data,useInheritance);
+if(output){
+_utils2.default.outputReactFriendlyStyle(styleSheet,output,prettyPrint,literalObject);
+}
+return styleSheet;
+}},{key:'toJSS',value:function toJSS(
-stylesheetString){var useInheritance=arguments.length<=1||arguments[1]===undefined?false:arguments[1];
+stylesheetString){var useInheritance=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;
var directions=['top','right','bottom','left'];
var changeArr=['margin','padding','border-width','border-radius'];
var numberize=_utils2.default.filterArray(['width','height','font-size','line-height'].concat(directions),useInheritance?_inheritance.numeric:[]);
-//special properties and shorthands that need to be broken down separately
+
var specialProperties={};
['border','border-top','border-right','border-bottom','border-left'].forEach(function(name){
specialProperties[name]={
@@ -55,7 +51,7 @@ numberize.push(prop+'-'+dir);
});
});
-//map of properties that when expanded use different directions than the default Top,Right,Bottom,Left.
+
var directionMaps={
'border-radius':{
'Top':'top-left',
@@ -65,23 +61,27 @@ var directionMaps={
-//Convert the shorthand property to the individual directions, handles edge cases, i.e. border-width and border-radius
+
+
function directionToPropertyName(property,direction){
var names=property.split('-');
names.splice(1,0,directionMaps[property]?directionMaps[property][direction]:direction);
return(0,_toCamelCase2.default)(names.join('-'));
}
-// CSS properties that are not supported by React Native
-// The list of supported properties is at https://facebook.github.io/react-native/docs/style.html#supported-properties
+
+
+
var unsupported=['display'];var _ParseCSS=
-(0,_cssParse2.default)(_utils2.default.clean(stylesheetString));var stylesheet=_ParseCSS.stylesheet;
+(0,_cssParse2.default)(_utils2.default.clean(stylesheetString)),stylesheet=_ParseCSS.stylesheet;
var JSONResult={};
-for(var _iterator=stylesheet.rules,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[typeof Symbol==='function'?Symbol.iterator:'@@iterator']();;){var _ref;if(_isArray){if(_i>=_iterator.length)break;_ref=_iterator[_i++];}else{_i=_iterator.next();if(_i.done)break;_ref=_i.value;}var rule=_ref;
-if(rule.type!=='rule')continue;var _loop=function _loop(_selector){
+for(var _iterator=stylesheet.rules,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[typeof Symbol==='function'?Symbol.iterator:'@@iterator']();;){var _ref2;if(_isArray){if(_i>=_iterator.length)break;_ref2=_iterator[_i++];}else{_i=_iterator.next();if(_i.done)break;_ref2=_i.value;}var rule=_ref2;
+if(rule.type!=='rule'){
+continue;
+}var _loop=function _loop(_selector){
if(!useInheritance){
@@ -92,7 +92,9 @@ var styles=JSONResult[_selector]=JSONResult[_selector]||{};var _loop2=function _
declaration){
-if(declaration.type!=='declaration')return'continue';
+if(declaration.type!=='declaration'){
+return'continue';
+}
var value=declaration.value;
var property=declaration.property;
@@ -118,7 +120,9 @@ return'continue';
}
}
-if(_utils2.default.arrayContains(property,unsupported))return'continue';
+if(_utils2.default.arrayContains(property,unsupported)){
+return'continue';
+}
if(_utils2.default.arrayContains(property,numberize)){
styles[(0,_toCamelCase2.default)(property)]=parseFloat(value.replace(/px|\s*/g,''));
@@ -173,8 +177,8 @@ declaration.value=parseFloat(declaration.value);
}
styles[(0,_toCamelCase2.default)(property)]=declaration.value;
-}};for(var _iterator3=rule.declarations,_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[typeof Symbol==='function'?Symbol.iterator:'@@iterator']();;){var _ref3;if(_isArray3){if(_i3>=_iterator3.length)break;_ref3=_iterator3[_i3++];}else{_i3=_iterator3.next();if(_i3.done)break;_ref3=_i3.value;}var declaration=_ref3;var _ret2=_loop2(declaration);if(_ret2==='continue')continue;
-}selector=_selector;};for(var _iterator2=rule.selectors,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[typeof Symbol==='function'?Symbol.iterator:'@@iterator']();;){var _ref2;if(_isArray2){if(_i2>=_iterator2.length)break;_ref2=_iterator2[_i2++];}else{_i2=_iterator2.next();if(_i2.done)break;_ref2=_i2.value;}var selector=_ref2;var values;var length;_loop(selector);
+}};for(var _iterator3=rule.declarations,_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[typeof Symbol==='function'?Symbol.iterator:'@@iterator']();;){var _ref4;if(_isArray3){if(_i3>=_iterator3.length)break;_ref4=_iterator3[_i3++];}else{_i3=_iterator3.next();if(_i3.done)break;_ref4=_i3.value;}var declaration=_ref4;var _ret2=_loop2(declaration);if(_ret2==='continue')continue;
+}selector=_selector;};for(var _iterator2=rule.selectors,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[typeof Symbol==='function'?Symbol.iterator:'@@iterator']();;){var _ref3;if(_isArray2){if(_i2>=_iterator2.length)break;_ref3=_iterator2[_i2++];}else{_i2=_iterator2.next();if(_i2.done)break;_ref3=_i2.value;}var selector=_ref3;var values;var length;_loop(selector);
}
}
return useInheritance?(0,_inheritance2.default)(JSONResult):JSONResult;
diff --git a/build/inheritance.js b/build/inheritance.js
new file mode 100644
index 0000000..93a9445
--- /dev/null
+++ b/build/inheritance.js
@@ -0,0 +1,112 @@
+Object.defineProperty(exports,"__esModule",{value:true});exports.numeric=undefined;var _extends=Object.assign||function(target){for(var i=1;i\s*/g,">").replace(/\s+/g," ");select.split(" ").forEach(function(part){part.split(">").forEach(function(key,i){target=target[key]||(target[key]={});target._isDirectDescendent=i>0;});});_extends(target,styles[selector]);});};for(var _iterator=Object.keys(styles),_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[typeof Symbol==="function"?Symbol.iterator:"@@iterator"]();;){var _ref;if(_isArray){if(_i>=_iterator.length)break;_ref=_iterator[_i++];}else{_i=_iterator.next();if(_i.done)break;_ref=_i.value;}var selector=_ref;_loop(selector);}return tree;}function getInheritedProperties(state,node,rootState){state=_extends({},state);textProps.forEach(function(prop){if(node&&node[prop]){var value=node[prop];if(numericProps.indexOf(prop)>-1&&typeof value==="string"){var numericValue=parseFloat(value.replace(/[^0-9\.]/g,"")),isRelativeToRoot=value.indexOf("rem")>-1,isRelative=value.indexOf("em")>-1;if(isRelativeToRoot){numericValue*=rootState[prop];}else if(isRelative){numericValue*=state[prop]||0;}node[prop]=~~numericValue;}state[prop]=node[prop];}});return state;}function cleanInherits(inherited,node){var keys=Object.keys(node),clean={};Object.keys(inherited).forEach(function(key){if(keys.indexOf(key)===-1){clean[key]=inherited[key];}});return clean;}function inherit(node,state,rootState){if(!state){rootState=_extends({},defaultRootState,node.root);rootState=state=getInheritedProperties(rootState,node.root,rootState);}var cleanNode={};for(var _iterator2=Object.keys(node),_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[typeof Symbol==="function"?Symbol.iterator:"@@iterator"]();;){var _ref2;if(_isArray2){if(_i2>=_iterator2.length)break;_ref2=_iterator2[_i2++];}else{_i2=_iterator2.next();if(_i2.done)break;_ref2=_i2.value;}var key=_ref2;var childNode=node[key];var textPsuedo=key.toLowerCase().indexOf(":text")>-1;key=key.replace(/:text/i,"");if((key.toLowerCase().indexOf("text")===0||textPsuedo)&&typeof childNode==="object"){cleanNode[key+"&inherited"]=cleanInherits(getInheritedProperties(state,childNode,rootState),childNode);cleanNode[key]=childNode;}else if(childNode&&typeof childNode==="object"){cleanNode[key]=inherit(childNode,getInheritedProperties(state,childNode,rootState),rootState);}else if(textProps.indexOf(key)===-1){cleanNode[key]=childNode;}}return cleanNode;}function flatten(tree){var flatObject=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var name=arguments.length>2&&arguments[2]!==undefined?arguments[2]:"";var flatStyle={};for(var _iterator3=Object.keys(tree),_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[typeof Symbol==="function"?Symbol.iterator:"@@iterator"]();;){var _ref3;if(_isArray3){if(_i3>=_iterator3.length)break;_ref3=_iterator3[_i3++];}else{_i3=_iterator3.next();if(_i3.done)break;_ref3=_i3.value;}var key=_ref3;var value=tree[key],isDirectDescendent=value._isDirectDescendent;if(typeof value==="object"){flatten(value,flatObject,name+(isDirectDescendent?">":" ")+key);}else if(key!=="_isDirectDescendent"){flatStyle[key]=value;}}if(Object.keys(flatStyle).length>0){flatObject[name.trim()]=flatStyle;}return flatObject;}function inheritance(styles){
+return flatten(inherit(expandStyles(styles)));
+}exports.
+numeric=numeric;
\ No newline at end of file
diff --git a/build/utils.js b/build/utils.js
index 6681a6f..6eddb37 100644
--- a/build/utils.js
+++ b/build/utils.js
@@ -1,4 +1,4 @@
-Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i"+element.e+"."+element.c.join(".")+":"+(element.i||"")+":"+(element.f||"")+":"+(element.l||"");
+if(this.cssPathKey!==key){
+
+
+
+this.cssPath=pathCache[key]||(pathCache[key]=(this.context.cssPath||[{e:"root"}]).concat([element]));
+this.cssPathKey=key;
+}
+}},{key:"render",value:function render()
+
+{var _this2=this;
+return _react2.default.createElement(WrappedComponent,_extends({},this.props,{ref:function ref(_ref){return _this2._root=_ref;},
+style:this.props.style?[this.styles,this.props.style]:this.styles}));
+}},{key:"pathKey",get:function get(){if(!this.cssPathKey||this.context.cssPathKey!==this._lastPathKey){this.createPath(this.props);this._lastPathKey=this.context.cssPathKey;}return this.cssPathKey;}},{key:"styles",get:function get(){if(!this.style||this._lastKey!==this.pathKey){if(!this.cssPath){this.createPath(this.props);}var style=(0,_css.matchingRules)(this.cssPath,this.cssPathKey);this.style=this.props.style?(0,_css2.default)(style,this.props.style):style;this._lastKey=this.pathKey;}return this.style;}}]);return StyledComponent;}(_react.Component);
+
+
+(0,_hoistNonReactStatics2.default)(StyledComponent,WrappedComponent);
+StyledComponent.WrappedComponent=WrappedComponent;
+StyledComponent.displayName=name;
+StyledComponent.childContextTypes={
+cssPath:_react2.default.PropTypes.array,
+cssPathKey:_react2.default.PropTypes.string};
+
+
+StyledComponent.contextTypes={cssPath:_react2.default.PropTypes.array,cssPathKey:_react2.default.PropTypes.string};
+return StyledComponent;
+}
\ No newline at end of file
diff --git a/circle.yml b/circle.yml
index 40c3f4c..9e3f894 100644
--- a/circle.yml
+++ b/circle.yml
@@ -1,7 +1,12 @@
+machine:
+ node:
+ version: 6.1.0
+
dependencies:
pre:
+ - npm install -g npm
- npm install
- - npm install -g babel
+ - npm rebuild
test:
override:
diff --git a/examples/README.md b/examples/README.md
index 2b50f3f..f00253f 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -30,7 +30,7 @@ You can use the wrapped style components instead of those out of the `react-nati
### Create your stylesheet
You create your CSS styles normally, however remember that React Native only supports a small subset of style properties that can be mapped to CSS. See [http://facebook.github.io/react-native/docs/view.html#style](http://facebook.github.io/react-native/docs/view.html#style) for more information.
-Also, only a small subset of selectors are supported. Components (including `*`), classes, child (`>`) and `:not(.className)` are supported and `:first-child`, `:nth-child(n)` and `:last-child` are supported only if the components are immediately wrapped with the *map* function.
+Also, only a small subset of selectors are supported. Components (including `*`), classes, child (`>`), `:not(.className)`,`:first-child`, `:nth-child(n)` and `:last-child` are supported.
There is currently **no** support for siblings (`+`,`~`), props (`[name="value"]`) or the myriad of pseudo-class selectors.
Also, styles for text must be in a selector that terminates in a text component (compound selectors are okay, e.g. `text.someClass:first-child`). This is because text styles are filtered out of all other selectors when the CSS is converted.
@@ -51,14 +51,13 @@ root {
//This will take precedence over the text {...} rule
font-size: 22px;
color: $myAwesomeColor;
- //If you wrap components in the map method, you can use child-position pseudo selectors.
&:last-child {
font-weight: bold;
}
}
-//You need to either style a text component or specify that a selector is a // text element using the :text pseudo selector.
-.someTextClass:text {
+//You need to explicitly style a text component for text properties to apply
+text.someTextClass {
font-size:20px;
}
@@ -120,7 +119,7 @@ register(require('./styles/default.js'), require('./styles/ios_theme.js'))
//MyComponent.js
import React,{Component} from 'react'
//use react-native-css as a drop-in replacement for react-native
-import {View,Text,TouchableOpacity,wrap,map} from 'react-native-css'
+import {View,Text,TouchableOpacity,wrap} from 'react-native-css'
class MyComponent extends Component {
render() {
@@ -168,7 +167,6 @@ class MyComponent extends Component {
export default MyComponent
-//Enable :last-child,:first-child and :nth-child(n) selectors using map([Component])
class MyComponent extends Component {
state = {
@@ -181,14 +179,9 @@ class MyComponent extends Component {
//Here we can do a short circuit for the 'active' class and let the library do the ugly work.
return (
- {//map will automatically add keys (index) if not set. This is fine for static arrays, however set keys for dynamic children to prevent state issues.
- map([
- This is some text that will be automatically styled with text element selector (.my-component text:first-child {'{...}'}).,
- This is some text that will be automatically styled with text element selector (.my-component text:nth-child(2) {'{...}'}).,
- This is some text that will be automatically styled with text element selector (.my-component text:last-child {'{...}'}).
- ])
- //just wrap an Array#map() call to get functionality on a dynamic set, e.g. map(someArray.map(item=>))
- }
+ This is some text that will be automatically styled with text element selector (.my-component text:first-child {'{...}'}).
+ This is some text that will be automatically styled with text element selector (.my-component text:nth-child(2) {'{...}'}).
+ This is some text that will be automatically styled with text element selector (.my-component text:last-child {'{...}'}).
this.setState({someActiveFlag:true})}>
@@ -232,9 +225,6 @@ Rules are ordered by how well they match the path of a component and ordered fro
### className
The *className* property is slightly different than how it implemented in standard React. Standard React only excepts a string as the value, while this library will accept either a string or an array of strings or string arrays. If you use this library in a web environment, className is passed unaltered which means you can only pass a string. If you use it in web environments, wrap the className arrays with the `normalizeClassNames` functions which will convert the array into a string.
-### :first-child, :last-child, :nth-child(n)
-Because we use standardized Context to calculate a component's position in the tree, it is impossible to infer a component's position amongst its siblings. To overcome this we have the `map` function to clone each child aware of its position amongst its siblings in the passed array. Without using `map` these pseudo classes will not work.
-
### Running in the browser
If you plan on using the fantastic *react-native-web* in order to run your React Native app in the browser, you should know that this library becomes a no op meaning any library specific features can't be used. This is a performance consideration as it is much less expensive to defer to the browsers native CSS operations.
diff --git a/package.json b/package.json
index 2171e91..c7474c2 100644
--- a/package.json
+++ b/package.json
@@ -12,29 +12,32 @@
"author": "Sabeur Thabti",
"license": "MIT",
"dependencies": {
+ "babel-polyfill": "^6.13.0",
"chokidar": "^1.4.1",
"colors": "^1.1.2",
"css-parse": "^2.0.0",
"cssauron": "^1.4.0",
+ "debug": "^2.2.0",
+ "fs-extra": "^2.0.0",
"hoist-non-react-statics": "^1.2.0",
"minimist": "^1.1.1",
- "node-sass": "^3.3.2",
+ "node-sass": "^4.5.0",
"npm-web-api": "^0.1.1",
- "react": "~15.2.1",
- "react-native": "^0.31.0",
- "request": "^2.67.0",
+ "react": "~15.4.2",
+ "react-native": "^0.41.2",
+ "request": "^2.74.0",
"to-camel-case": "~1.0.0"
},
"devDependencies": {
"babel-cli": "^6.11.0",
- "babel-eslint": "^6.1.2",
- "babel-jest": "^14.1.0",
+ "babel-eslint": "^7.1.1",
+ "babel-jest": "^19.0.0",
"babel-polyfill": "^6.13.0",
"babel-preset-react-native": "^1.9.0",
"eslint": "^3.3.0",
"eslint-plugin-react": "^6.0.0",
- "jest-cli": "^14.1.0",
- "jest-react-native": "^14.1.2",
+ "jest-cli": "^19.0.2",
+ "jest-react-native": "^18.0.0",
"react-test-renderer": "^15.3.0"
},
"jest": {
diff --git a/src/babelTransform.js b/src/babelTransform.js
new file mode 100644
index 0000000..ea99e9a
--- /dev/null
+++ b/src/babelTransform.js
@@ -0,0 +1,44 @@
+import RNC from './index';
+import path from 'path';
+import {spawn} from 'child_process';
+const css = new RNC();
+
+function runWatcher(input, output) {
+ spawn('node', ['./watcher.js', input, output], {detached: true, cwd: __dirname});
+}
+
+function startTransform(input, output) {
+
+ css.parse({
+ input,
+ output,
+ useInheritance: true
+ });
+
+ if (process.env.BABEL_ENV === 'development') {
+ runWatcher(input, output);
+ }
+ return true;
+}
+
+//
+
+export default function ({ types: t }) {
+ return {
+ visitor: {
+ ImportDeclaration (transformPath, {file}) {
+ let resolvePath = transformPath.node.source.value;
+ if (resolvePath.startsWith('css!')) {
+ resolvePath = resolvePath.substr(4);
+ let name = resolvePath.replace(/\.\.\/|\.\//g, '').replace(/\//g, '_').split('.')[0];
+ let absolutePath = path.resolve(path.dirname(file.opts.filename), resolvePath),
+ relativePath = `${path.dirname(absolutePath)}/_transformed/${name}.js`;
+ startTransform(absolutePath, path.resolve(relativePath));
+
+ let expression = (t.callExpression(t.memberExpression(t.callExpression(t.identifier('require'), [t.stringLiteral('react-native-css')]), t.identifier('register')), [t.callExpression(t.identifier('require'), [path.resolve(relativePath)])]));
+ transformPath.replaceWith(expression);
+ }
+ }
+ }
+ };
+}
diff --git a/src/client.js b/src/client.js
index 4d3b316..dea9ed4 100644
--- a/src/client.js
+++ b/src/client.js
@@ -1,6 +1,6 @@
import ReactNative from "react-native";
import css,{register,unregister} from "./css";
-import wrap,{map} from "./wrap";
+import wrap from "./wrap";
//These are all the components in react native to wrap with the styled proxy component
const componentsToWrap = ["ActivityIndicator",
@@ -76,6 +76,5 @@ StyledComponents.unregister = unregister;
StyledComponents.register = register;
StyledComponents.css = css;
StyledComponents.wrap = wrap;
-StyledComponents.map = map;
module.exports = StyledComponents;
diff --git a/src/index.js b/src/index.js
index 984a4e5..2cfd937 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,36 +5,32 @@ import inheritance,{numeric} from './inheritance';
export default class ReactNativeCss {
- async parse(input, output = './style.js', prettyPrint = false, literalObject = false, useInheritance = false) {
- if(utils.contains(input, /scss/)) {
-
+ parse({input, output, prettyPrint = false, literalObject = false, useInheritance = false}) {
+ if (!input) {
+ throw new Error('An input file is required.');
+ }
+ let data;
+ if (utils.contains(input, /scss/)) {
let {css} = require('node-sass').renderSync({
file: input,
outputStyle: 'compressed'
});
-
- let styleSheet = this.toJSS(css.toString(),useInheritance);
- if(output)
- utils.outputReactFriendlyStyle(styleSheet, output, prettyPrint, literalObject);
- return styleSheet;
-
+ data = css.toString();
} else {
- return await new Promise((resolve,reject)=>utils.readFile(input, (err, data) => {
- if (err) {
- return reject(err);
- }
- let styleSheet = this.toJSS(data,useInheritance);
- if(output)
- utils.outputReactFriendlyStyle(styleSheet, output, prettyPrint, literalObject);
- resolve(styleSheet);
- }));
+ data = utils.readFile(input);
}
+
+ let styleSheet = this.toJSS(data, useInheritance);
+ if (output) {
+ utils.outputReactFriendlyStyle(styleSheet, output, prettyPrint, literalObject);
+ }
+ return styleSheet;
}
- toJSS(stylesheetString,useInheritance=false) {
+ toJSS(stylesheetString, useInheritance = false) {
const directions = ['top', 'right', 'bottom', 'left'];
const changeArr = ['margin', 'padding', 'border-width', 'border-radius'];
- const numberize = utils.filterArray(['width', 'height', 'font-size', 'line-height'].concat(directions),useInheritance?numeric:[]);
+ const numberize = utils.filterArray(['width', 'height', 'font-size', 'line-height'].concat(directions), useInheritance ? numeric : []);
//special properties and shorthands that need to be broken down separately
const specialProperties = {};
['border', 'border-top', 'border-right', 'border-bottom', 'border-left'].forEach(name=> {
@@ -57,23 +53,25 @@ export default class ReactNativeCss {
//map of properties that when expanded use different directions than the default Top,Right,Bottom,Left.
const directionMaps = {
- 'border-radius':{
- 'Top':'top-left',
- 'Right':'top-right',
- 'Bottom':'bottom-right',
+ 'border-radius': {
+ 'Top': 'top-left',
+ 'Right': 'top-right',
+ 'Bottom': 'bottom-right',
'Left': 'bottom-left'
}
};
- //Convert the shorthand property to the individual directions, handles edge cases, i.e. border-width and border-radius
- function directionToPropertyName(property,direction){
+ //Convert the shorthand property to the individual directions, handles edge cases, i.e. border-width and
+ // border-radius
+ function directionToPropertyName(property, direction) {
let names = property.split('-');
- names.splice(1,0,directionMaps[property]?directionMaps[property][direction]:direction);
+ names.splice(1, 0, directionMaps[property] ? directionMaps[property][direction] : direction);
return toCamelCase(names.join('-'));
}
// CSS properties that are not supported by React Native
- // The list of supported properties is at https://facebook.github.io/react-native/docs/style.html#supported-properties
+ // The list of supported properties is at
+ // https://facebook.github.io/react-native/docs/style.html#supported-properties
const unsupported = ['display'];
let {stylesheet} = ParseCSS(utils.clean(stylesheetString));
@@ -81,7 +79,9 @@ export default class ReactNativeCss {
let JSONResult = {};
for (let rule of stylesheet.rules) {
- if (rule.type !== 'rule') continue;
+ if (rule.type !== 'rule') {
+ continue;
+ }
for (let selector of rule.selectors) {
if (!useInheritance) {
@@ -92,7 +92,9 @@ export default class ReactNativeCss {
for (let declaration of rule.declarations) {
- if (declaration.type !== 'declaration') continue;
+ if (declaration.type !== 'declaration') {
+ continue;
+ }
let value = declaration.value;
let property = declaration.property;
@@ -118,7 +120,9 @@ export default class ReactNativeCss {
}
}
- if (utils.arrayContains(property, unsupported)) continue;
+ if (utils.arrayContains(property, unsupported)) {
+ continue;
+ }
if (utils.arrayContains(property, numberize)) {
styles[toCamelCase(property)] = parseFloat(value.replace(/px|\s*/g, ''));
diff --git a/src/utils.js b/src/utils.js
index b0665aa..c93c05a 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,4 +1,4 @@
-import fs from "fs";
+import fs from "fs-extra";
export default class Utils {
static arrayContains(value, arr) {
@@ -18,8 +18,8 @@ export default class Utils {
return string.replace(/\r?\n|\r/g, "");
}
- static readFile(file, cb) {
- fs.readFile(file, "utf8", cb);
+ static readFile(file) {
+ return fs.readFileSync(file, "utf8");
}
static outputReactFriendlyStyle(style, outputFile, prettyPrint, literalObject) {
@@ -28,8 +28,10 @@ export default class Utils {
var output = "module.exports = ";
output += (literalObject) ? `${jsonOutput}` : `require('react-native').StyleSheet.create(${jsonOutput});`;
// Write to file
- if(outputFile)
+ if (outputFile) {
+ fs.ensureFileSync(outputFile);
fs.writeFileSync(outputFile, output);
+ }
return output;
}
diff --git a/src/watcher.js b/src/watcher.js
new file mode 100644
index 0000000..8f90d43
--- /dev/null
+++ b/src/watcher.js
@@ -0,0 +1,66 @@
+import 'babel-polyfill';
+import RNC from './index';
+import fs from 'fs';
+import request from 'request';
+import chokidar from 'chokidar';
+
+const css = new RNC();
+
+/**
+ * Checks if the packager is running, if not there really isn't point of keeping this thing alive.
+ * @return {Promise}
+ */
+function isServerRunning() {
+ return new Promise(resolve=>request('http://localhost:8081/status', (err, response, body)=> {
+ resolve(body === "packager-status:running");
+ }));
+}
+
+async function run() {
+ let input = process.argv[2],
+ output = process.argv[3];
+
+ if (!input || !output) {
+ return;
+ }
+
+ //check pid
+ let name = input.replace(/[^0-9a-z]/g, ''),
+ pidFile = `/tmp/rnc_watch_${name}.pid`;
+
+ function check() {
+ try {
+ return process.kill(~~fs.readFileSync(pidFile, 'utf8'), 0);
+ }
+ catch (e) {
+ return e.code === 'EPERM';
+ }
+ }
+
+ if (check()) {
+ return process.exit(0);
+ }
+
+ fs.writeFileSync(pidFile, process.pid, 'utf8');
+
+ //check if server is up
+ if (!(await isServerRunning())) {
+ return process.exit(0);
+ }
+
+ chokidar.watch(input, {
+ ignored: /[\/\\]\./, persistent: true
+ }).on('change', function () {
+ css.parse({input, output, useInheritance: true});
+ });
+
+ setInterval(async ()=> {
+ if (!(await isServerRunning())) {
+ process.exit(0);
+ }
+ }, 10000);
+
+}
+
+
+run();
diff --git a/src/wrap.js b/src/wrap.js
index 6ef06e0..e82080b 100644
--- a/src/wrap.js
+++ b/src/wrap.js
@@ -28,31 +28,17 @@ function normalizeClassNames(classNames) {
return classes;
}
-/**
- * This takes an array of components and adds position properties for leveraging :first-child, :last-child,
- * :nth-child(1...n) selectors. Without these properties, those selectors will fail.
- * Passing a single component will result in first,last and nth(1) all succeeding.
- * A key is automatically added (just the index) if omitted, which allows easily adding this to static children.
- * @param {[Component]|Component} componentOrComponentArray
- * @return {*}
- */
-function map(componentOrComponentArray) {
- componentOrComponentArray = (componentOrComponentArray instanceof Array ? componentOrComponentArray : [componentOrComponentArray]);
- if (isWebApp) {
- //css pseudo already supported in the browser
- return componentOrComponentArray;
+function indexOf(instance, children) {
+ let index = 0;
+ for (let key in children) {
+ if (children[key]._mountOrder === instance._reactInternalInstance._mountOrder) {
+ return index;
+ }
+ index++;
}
- return componentOrComponentArray.map((component, i)=> {
- return React.cloneElement(component, {
- firstChild: i === 0,
- lastChild: i === componentOrComponentArray.length - 1,
- nthChild: i + 1,
- key: i
- });
- });
+ return -1;
}
-
const pathCache = {};
/**
@@ -119,8 +105,8 @@ export default function wrap(name, WrappedComponent) {
this._root && this._root.setNativeProps(nativeProps);
}
- shouldComponentUpdate() {
- return false;
+ shouldComponentUpdate(nextProps) {
+ return shallowCompare(this, nextProps);
}
/**
@@ -128,14 +114,21 @@ export default function wrap(name, WrappedComponent) {
* @param props
*/
createPath(props) {
+ let index = -1,
+ count = 1;
+ if (this._reactInternalInstance && this._reactInternalInstance._hostParent) {
+ let children = this._reactInternalInstance._hostParent._renderedChildren;
+ count = Object.keys(children).length;
+ index = indexOf(this, children);
+ }
let element = {
e: name.toLowerCase(),
c: normalizeClassNames(props.className),
//Maybe in the future, but is it worth the performance hit?
// p: props,
- i: props.nthChild || -1,
- f: props.firstChild || false,
- l: props.lastChild || false
+ i: index,
+ f: index === 0,
+ l: count === index + 1
};
let key = `${this.context.cssPathKey || ""}>${element.e}.${element.c.join(".")}:${element.i || ""}:${element.f || ""}:${element.l || ""}`;
if (this.cssPathKey !== key) {
@@ -148,8 +141,8 @@ export default function wrap(name, WrappedComponent) {
}
render() {
- let props = {ref: ref=>this._root = ref, style: this.styles};
- return ;
+ return this._root = ref}
+ style={this.props.style?[this.styles,this.props.style]:this.styles}/>;
}
};
@@ -164,5 +157,3 @@ export default function wrap(name, WrappedComponent) {
StyledComponent.contextTypes = {cssPath: React.PropTypes.array, cssPathKey: React.PropTypes.string};
return StyledComponent;
}
-
-export {map};