├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── .npmrc ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── package.json ├── src └── reactNativeInterface.js └── test ├── .eslintrc ├── _helpers └── reactNativeMock.js └── reactNativeInterface_test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["airbnb"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb-base", 3 | 4 | "env": { 5 | "browser": true, 6 | "node": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # Built files 40 | /lib 41 | 42 | # Only apps should have lockfiles 43 | npm-shrinkwrap.json 44 | package-lock.json 45 | yarn.lock 46 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - "6" 5 | - "5" 6 | - "4" 7 | - "4.2" 8 | script: 'if [ "${TRAVIS_NODE_VERSION}" = 6 ]; then npm test; else npm run tests-only; fi' 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v1.0.0 2 | 3 | - Initial release. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Airbnb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-with-styles-interface-react-native [![Version Badge][npm-version-svg]][package-url] 2 | 3 | [![Build Status][travis-svg]][travis-url] 4 | [![dependency status][deps-svg]][deps-url] 5 | [![dev dependency status][dev-deps-svg]][dev-deps-url] 6 | [![License][license-image]][license-url] 7 | [![Downloads][downloads-image]][downloads-url] 8 | 9 | [![npm badge][npm-badge-png]][package-url] 10 | 11 | Interface to use [react-with-styles][react-with-styles] with [React Native][react-native]. 12 | 13 | [package-url]: https://npmjs.org/package/react-with-styles-interface-react-native 14 | [npm-version-svg]: http://versionbadg.es/airbnb/react-with-styles-interface-react-native.svg 15 | [travis-svg]: https://travis-ci.org/airbnb/react-with-styles-interface-react-native.svg 16 | [travis-url]: https://travis-ci.org/airbnb/react-with-styles-interface-react-native 17 | [deps-svg]: https://david-dm.org/airbnb/react-with-styles-interface-react-native.svg 18 | [deps-url]: https://david-dm.org/airbnb/react-with-styles-interface-react-native 19 | [dev-deps-svg]: https://david-dm.org/airbnb/react-with-styles-interface-react-native/dev-status.svg 20 | [dev-deps-url]: https://david-dm.org/airbnb/react-with-styles-interface-react-native#info=devDependencies 21 | [npm-badge-png]: https://nodei.co/npm/react-with-styles-interface-react-native.png?downloads=true&stars=true 22 | [license-image]: http://img.shields.io/npm/l/react-with-styles-interface-react-native.svg 23 | [license-url]: LICENSE 24 | [downloads-image]: http://img.shields.io/npm/dm/react-with-styles-interface-react-native.svg 25 | [downloads-url]: http://npm-stat.com/charts.html?package=react-with-styles-interface-react-native 26 | 27 | [react-with-styles]: https://github.com/airbnb/react-with-styles 28 | [react-native]: https://facebook.github.io/react-native/ 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-with-styles-interface-react-native", 3 | "version": "1.0.0", 4 | "description": "react-with-styles interface for React Native", 5 | "main": "lib/reactNativeInterface.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "build": "npm run clean && babel src/ -d lib/", 11 | "check-changelog": "expr $(git status --porcelain 2>/dev/null| grep \"^\\s*M.*CHANGELOG.md\" | wc -l) >/dev/null || (echo 'Please edit CHANGELOG.md' && exit 1)", 12 | "check-only-changelog-changed": "(expr $(git status --porcelain 2>/dev/null| grep -v \"CHANGELOG.md\" | wc -l) >/dev/null && echo 'Only CHANGELOG.md may have uncommitted changes' && exit 1) || exit 0", 13 | "clean": "rimraf lib", 14 | "lint": "eslint .", 15 | "mocha": "mocha --compilers js:babel-register,jsx:babel-register --require airbnb-js-shims --recursive test/_helpers test", 16 | "postversion": "git commit package.json CHANGELOG.md -m \"Version $npm_package_version\" && npm run tag && git push && git push --tags && npm publish", 17 | "prepublish": "in-publish && safe-publish-latest && npm run build || not-in-publish", 18 | "pretest": "npm run --silent lint", 19 | "preversion": "npm run test && npm run check-changelog && npm run check-only-changelog-changed", 20 | "tag": "git tag v$npm_package_version", 21 | "test": "npm run tests-only", 22 | "tests-only": "npm run mocha --silent test", 23 | "version:major": "npm --no-git-tag-version version major", 24 | "version:minor": "npm --no-git-tag-version version minor", 25 | "version:patch": "npm --no-git-tag-version version patch" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "git+https://github.com/airbnb/react-with-styles-interface-react-native.git" 30 | }, 31 | "keywords": [ 32 | "react-with-styles", 33 | "react native" 34 | ], 35 | "author": "Joe Lencioni ", 36 | "license": "MIT", 37 | "bugs": { 38 | "url": "https://github.com/airbnb/react-with-styles-interface-react-native/issues" 39 | }, 40 | "homepage": "https://github.com/airbnb/react-with-styles-interface-react-native#readme", 41 | "devDependencies": { 42 | "airbnb-js-shims": "^1.3.0", 43 | "babel-cli": "^6.26.0", 44 | "babel-preset-airbnb": "^2.4.0", 45 | "babel-register": "^6.26.0", 46 | "chai": "^4.1.2", 47 | "eslint": "^4.10.0", 48 | "eslint-config-airbnb-base": "^12.1.0", 49 | "eslint-plugin-import": "^2.8.0", 50 | "in-publish": "^2.0.0", 51 | "mocha": "^4.0.1", 52 | "react": "~15.4", 53 | "react-dom": "~15.4", 54 | "react-native": "^0.42.0", 55 | "react-native-mock": "^0.3.1", 56 | "rimraf": "^2.6.2", 57 | "safe-publish-latest": "^1.1.1" 58 | }, 59 | "peerDependencies": { 60 | "react-native": ">= 0.8.0" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/reactNativeInterface.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | 3 | export default { 4 | create(styleHash) { 5 | return StyleSheet.create(styleHash); 6 | }, 7 | 8 | // Styles is an array of properties returned by `create()`, a POJO, or an 9 | // array thereof. POJOs are treated as inline styles. 10 | // This function returns an object to be spread onto an element. 11 | resolve(styles) { 12 | return { style: styles }; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "rules": { 6 | "import/no-extraneous-dependencies": [2, { 7 | "devDependencies": true 8 | }] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/_helpers/reactNativeMock.js: -------------------------------------------------------------------------------- 1 | // This file is mostly copied from 2 | // https://github.com/lelandrichardson/react-native-mock/blob/master/mock.js 3 | const ReactNativeMock = require('react-native-mock/build/react-native'); 4 | 5 | // Monkey-patch react-native-mock's StyleSheet.create to behave more like 6 | // react-native does. 7 | ReactNativeMock.StyleSheet.create = function create(obj) { 8 | return Object.keys(obj).reduce((res, key, index) => { 9 | // eslint-disable-next-line no-param-reassign 10 | res[key] = index; 11 | return res; 12 | }, {}); 13 | }; 14 | 15 | // the cache key that real react native would get 16 | const key = require.resolve('react-native'); 17 | 18 | // make sure the cache is filled with our lib 19 | require.cache[key] = { 20 | id: key, 21 | filename: key, 22 | loaded: true, 23 | exports: ReactNativeMock, 24 | }; 25 | -------------------------------------------------------------------------------- /test/reactNativeInterface_test.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | 3 | import reactNativeInterface from '../src/reactNativeInterface'; 4 | 5 | describe('reactNativeInterface', () => { 6 | describe('.create()', () => { 7 | it('processes the styles', () => { 8 | expect(reactNativeInterface.create({ 9 | foo: { 10 | color: 'red', 11 | }, 12 | })).to.eql({ 13 | foo: 0, 14 | }); 15 | }); 16 | }); 17 | 18 | describe('.resolve()', () => { 19 | it('returns processed styles', () => { 20 | const styles = reactNativeInterface.create({ 21 | foo: { 22 | color: 'red', 23 | }, 24 | }); 25 | 26 | expect(reactNativeInterface.resolve([styles.foo])) 27 | .to.eql({ style: [styles.foo] }); 28 | }); 29 | 30 | it('returns multiple processed styles', () => { 31 | const styles = reactNativeInterface.create({ 32 | foo: { 33 | color: 'red', 34 | }, 35 | 36 | bar: { 37 | display: 'inline-block', 38 | }, 39 | }); 40 | 41 | expect(reactNativeInterface.resolve([styles.foo, styles.bar])) 42 | .to.eql({ style: [styles.foo, styles.bar] }); 43 | }); 44 | 45 | it('handles an object with inline styles', () => { 46 | const style = { 47 | color: 'red', 48 | }; 49 | 50 | expect(reactNativeInterface.resolve([style])) 51 | .to.eql({ 52 | style: [{ 53 | color: 'red', 54 | }], 55 | }); 56 | }); 57 | 58 | it('handles multiple objects with inline styles', () => { 59 | const styleA = { 60 | color: 'red', 61 | }; 62 | 63 | const styleB = { 64 | display: 'inline-block', 65 | }; 66 | 67 | expect(reactNativeInterface.resolve([styleA, styleB])) 68 | .to.eql({ 69 | style: [ 70 | { color: 'red' }, 71 | { display: 'inline-block' }, 72 | ], 73 | }); 74 | }); 75 | 76 | it('handles a mix of processed and inline styles', () => { 77 | const styles = reactNativeInterface.create({ 78 | foo: { 79 | color: 'red', 80 | }, 81 | }); 82 | 83 | const style = { 84 | display: 'inline-block', 85 | }; 86 | 87 | expect(reactNativeInterface.resolve([styles.foo, style])) 88 | .to.eql({ 89 | style: [ 90 | styles.foo, 91 | { display: 'inline-block' }, 92 | ], 93 | }); 94 | }); 95 | 96 | it('handles nested arrays', () => { 97 | const styles = reactNativeInterface.create({ 98 | foo: { 99 | color: 'red', 100 | }, 101 | }); 102 | 103 | const styleA = { 104 | display: 'inline-block', 105 | }; 106 | 107 | const styleB = { 108 | padding: 1, 109 | }; 110 | 111 | expect(reactNativeInterface.resolve([[styles.foo], [[styleA, styleB]]])) 112 | .to.eql({ 113 | style: [ 114 | [styles.foo], 115 | [[ 116 | { display: 'inline-block' }, 117 | { padding: 1 }, 118 | ]], 119 | ], 120 | }); 121 | }); 122 | }); 123 | }); 124 | --------------------------------------------------------------------------------