├── .editorconfig ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json ├── src ├── debugger.js ├── defaultColors.js └── defaultOptions.js └── test └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | tab_width = 4 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '7' 4 | - '6' 5 | - '4' 6 | cache: 7 | directories: 8 | - node_modules 9 | notifications: 10 | slack: 11 | secure: "BDNxGvbnIyqGhup6lOInE/75OAIV4+cdq2a1XR/Lb3OhTHPcIou3AhBIrj0iD9+EyKWtSMEMpa8fbCd0/lARSr8jxz7RoSR6xxsGJjZ5eX9xSyvtec3y/zXfocBIaPJKJStrh/r01QPIbjOtnI3biYFZXvef/j91gO4qHOqOGDRv523ogdWJC/e69pbNl99glvCH8UXYVIvESMLJymMUizttOHdVo4051xPRqLRye+9UQLv5JXFh2f9p073OjKct3yMXysCrOClcpzEwQDAOo6o0QeOdcQN4m7lhwpbHBadTuZ8m2fEBD00ZbxLyXr2hsO1QZGRULoI9TqgeapoKpbXtpI/UDvKBo4HLKuO3z7XeWUqJsffzYaRTTCs8jcQHGL6nmfr4XmU098p6vRjo7+c+Alfr5C2+YLhhircGRRhvm36FJyBj5BoLne8TVt96EiIlDgzsg98DzmT8p4hq8CvWm45M4vlInHRBOOSiCS7G+p6kAVR92zxZybCJBD9W5NoV8UPvfC3mQqs/LvGCUCSKxNDMD15rNY+a6v/LNDsmXabUBTGxnuyETc4axyu0Iu5gAjQKnBpqdnMNCAcSqxKFy1wYt7VgnMy0XxDLeYqwNBpvw7Yr0vmfDxFvdBLCboGK3jiHpvZagwc77Xdy5usts4LnLvTtGJjc19LdT58=" 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017-2018 (c) Carlos Cuesta (https://carloscuesta.me) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-layout-debug 2 | 3 | [![Travis](https://img.shields.io/travis/com/carloscuesta/react-native-layout-debug?style=flat-square)](https://travis-ci.com/carloscuesta/react-native-layout-debug) 4 | [![npm version](https://img.shields.io/npm/v/react-native-layout-debug.svg?style=flat-square)](https://www.npmjs.com/package/react-native-layout-debug) 5 | [![npm-downloads](https://img.shields.io/npm/dt/react-native-layout-debug.svg?style=flat-square)](https://www.npmjs.com/package/react-native-layout-debug) 6 | [![Code Climate](https://img.shields.io/codeclimate/github/carloscuesta/react-native-layout-debug.svg?style=flat-square)](https://codeclimate.com/github/carloscuesta/react-native-layout-debug) 7 | 8 |

9 | 10 | react-native-layout-debug 11 | 12 |

13 | 14 | ## Install 15 | 16 | ```bash 17 | $ npm i --save react-native-layout-debug babel-plugin-transform-decorators-legacy 18 | ``` 19 | 20 | ## Usage 21 | 22 | Install and import the module inside your code. Update your .babelrc config and add `babel-plugin-transform-decorators-legacy` as a plugin. 23 | 24 | ```javascript 25 | import reactNativeLayoutDebug from 'react-native-layout-debug'; 26 | ``` 27 | 28 | To debug a layout component, you should call the `debug(color)` method inside the prop `style={}`. 29 | 30 | The **debug(color)** accepts a color to use as a border or background. If not provided will pick a random color from the list, normally you should specify a color by the name from the list, Eg: `debug('red')`. See the [defaultColors](https://github.com/carloscuesta/react-native-layout-debug/blob/master/src/defaultColors.js). 31 | 32 | If you don't like the default colors, you can provide an object of colors to the Debugger, see the [customization section](https://github.com/carloscuesta/react-native-layout-debug#customization). 33 | 34 | ```javascript 35 | class HelloWorld extends Component { 36 | // Using a custom config {style: 'background', colors: colorListObject} 37 | // @reactNativeDebug({style: 'background', colors: colorListObject}) 38 | // Using the default config {style: 'border', borderWidth: 3, colors: defaultColors}. 39 | @reactNativeLayoutDebug 40 | render(debug) { 41 | return ( 42 | 43 | Hey! 44 | 45 | ); 46 | } 47 | } 48 | ``` 49 | 50 | ## Customization 51 | 52 | The debugger could be customized via an object with these three properties: `style`, `colors` and `borderWidth`. 53 | 54 | #### `style` 55 | 56 | Specifies the style to use when debugging the layout, accepts two values: 57 | 58 | - `border`: **Default option**, uses borders to debug the layout elements. 59 | - `background`: Uses background to debug the layout elements. 60 | 61 | #### `colors` 62 | 63 | An **object of colors** that will be used by the debug. Look at [`defaultColors.js`](https://github.com/carloscuesta/react-native-layout-debug/blob/master/src/defaultColors.js) to see the default colors and the object used. 64 | 65 | #### `borderWidth` 66 | 67 | The **borderWidth** unit to use as border, by default is set to `3`. 68 | 69 | ## Demo 70 | 71 | react-native-layout-debug demo 72 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import Debugger from './src/debugger'; 2 | 3 | const defaultDebugger = new Debugger({}); 4 | 5 | /** 6 | * Debugger decorator 7 | * @param {Object} target 8 | * @param {String} name 9 | * @param {Function} descriptor 10 | * @return {Object} 11 | */ 12 | function debuggerDecorator(target, name, descriptor) { 13 | const layoutDebug = this; 14 | 15 | if (!descriptor) { 16 | return layoutDebug.debug.bind(layoutDebug); 17 | } 18 | 19 | const oldFunction = descriptor.value; 20 | 21 | descriptor.value = function () { 22 | return oldFunction.bind(this)(layoutDebug.debug.bind(layoutDebug)); 23 | }; 24 | 25 | return descriptor; 26 | } 27 | 28 | /** 29 | * Wrapper for debugger decorator to allow custom params 30 | * @return {Function} 31 | */ 32 | function getDebugger() { 33 | const isCustom = arguments.length === 1; 34 | const layoutDebug = isCustom ? new Debugger(arguments[0]) : defaultDebugger; 35 | return isCustom ? debuggerDecorator.bind(layoutDebug) : debuggerDecorator.call(layoutDebug, ...arguments); 36 | } 37 | 38 | export default getDebugger; 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-layout-debug", 3 | "version": "1.1.1", 4 | "description": "React native layout debugger.", 5 | "main": "index.js", 6 | "scripts": { 7 | "lint": "xo", 8 | "mocha": "cross-env BABEL_ENV=test mocha --compilers js:babel-core/register ./test/*.js", 9 | "test": "npm run lint && npm run mocha" 10 | }, 11 | "xo": { 12 | "esnext": true, 13 | "rules": { 14 | "unicorn/filename-case": [ 15 | "error", 16 | { 17 | "case": "camelCase" 18 | } 19 | ] 20 | }, 21 | "ignores": [ 22 | "test/**" 23 | ] 24 | }, 25 | "babel": { 26 | "env": { 27 | "test": { 28 | "presets": [ 29 | "es2015" 30 | ], 31 | "plugins": [ 32 | "transform-decorators-legacy" 33 | ] 34 | } 35 | } 36 | }, 37 | "repository": { 38 | "type": "git", 39 | "url": "git+https://github.com/carloscuesta/react-native-layout-debug.git" 40 | }, 41 | "keywords": [ 42 | "react-native", 43 | "layout", 44 | "debug", 45 | "debugger" 46 | ], 47 | "author": { 48 | "name": "Carlos Cuesta", 49 | "email": "crloscuesta@gmail.com", 50 | "url": "https://carloscuesta.me" 51 | }, 52 | "contributors": [ 53 | "Jordi López (http://jlopezxs.github.io)" 54 | ], 55 | "license": "MIT", 56 | "bugs": { 57 | "url": "https://github.com/carloscuesta/react-native-layout-debug/issues" 58 | }, 59 | "homepage": "https://github.com/carloscuesta/react-native-layout-debug#readme", 60 | "devDependencies": { 61 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 62 | "babel-core": "^6.21.0", 63 | "babel-preset-es2015": "^6.18.0", 64 | "cross-env": "^3.1.4", 65 | "mocha": "^3.2.0", 66 | "should": "^11.1.2", 67 | "xo": "^0.17.1" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/debugger.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import defaultColors from './defaultColors'; 4 | import defaultOptions from './defaultOptions'; 5 | 6 | class Debugger { 7 | 8 | /** 9 | * Debugger constructor 10 | * @param {String} style [Debugging style to use: border / background.] 11 | * @param {Integer} borderWidth [Specifies the borderWidth.] 12 | * @param {Object} colors [Object containing the colors used to debug.] 13 | */ 14 | constructor({style = defaultOptions.styles.border, borderWidth = defaultOptions.borderWidth, colors = defaultColors}) { 15 | this._style = style; 16 | this._borderWidth = borderWidth; 17 | this._colors = colors; 18 | } 19 | 20 | /** 21 | * Method that picks a random color from the colors Object. 22 | * @return {String} 23 | */ 24 | _getRandomColor() { 25 | const colorsKeys = Object.keys(this._colors); 26 | const randomColorKey = colorsKeys[Math.floor(Math.random() * colorsKeys.length)]; 27 | return this._colors[randomColorKey]; 28 | } 29 | 30 | /** 31 | * Method that returns a color Hex value by his name if specified, if not picks a random color from the list. 32 | * @param {String} colorName [Represents a color name from the list.] 33 | */ 34 | _getColor(colorName) { 35 | return this._colors[colorName] || this._getRandomColor(); 36 | } 37 | 38 | /** 39 | * Returns an object with the StyleSheet properties to use in an element. 40 | * @return {Object} 41 | */ 42 | _debugWithBorders(color) { 43 | return { 44 | borderColor: color, 45 | borderWidth: this._borderWidth 46 | }; 47 | } 48 | 49 | /** 50 | * Returns an object with the StyleSheet properties to use in an element. 51 | * @return {Object} 52 | */ 53 | _debugWithBackgrounds(color) { 54 | return { 55 | backgroundColor: color 56 | }; 57 | } 58 | 59 | /** 60 | * Sets the debug depending on the style and calls _debugWithBorders / _debugWithBackgrounds. 61 | * @param {String} colorName [Represents a specified color to use when debugging an element.] 62 | * @return {Object} 63 | */ 64 | debug(colorName) { 65 | const color = this._getColor(colorName); 66 | return (this._style === defaultOptions.styles.background) ? this._debugWithBackgrounds(color) : this._debugWithBorders(color); 67 | } 68 | } 69 | 70 | export default Debugger; 71 | -------------------------------------------------------------------------------- /src/defaultColors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * [defaultColors Object that contains the default colors used by the debug method.] 3 | * @type {Object} 4 | */ 5 | const defaultColors = { 6 | black: '#252525', 7 | red: '#FF5252', 8 | green: '#00E676', 9 | lime: '#C6FF00', 10 | yellow: '#FFEA00', 11 | orange: '#FF5722', 12 | blue: '#448AFF', 13 | pink: '#FF4081', 14 | purple: '#E040FB', 15 | cyan: '#18FFFF', 16 | white: '#FFFFFF' 17 | }; 18 | 19 | module.exports = defaultColors; 20 | -------------------------------------------------------------------------------- /src/defaultOptions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * [defaults Object that contains some of the default values for the Debugger class.] 3 | * @type {Object} 4 | */ 5 | const defaults = { 6 | styles: { 7 | border: 'border', 8 | background: 'background' 9 | }, 10 | borderWidth: 3 11 | }; 12 | 13 | module.exports = defaults; 14 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import Debugger from '../src/debugger'; 4 | import defaultColors from '../src/defaultColors'; 5 | import should from 'should'; 6 | 7 | const debug = new Debugger({ 8 | style: 'border', 9 | borderWidth: 4 10 | }); 11 | 12 | const debugBackground = new Debugger({ 13 | style: 'background' 14 | }); 15 | 16 | describe('react-native-layout-debug', () => { 17 | describe('debugWithBorders', () => { 18 | describe('when using the following object {color: #FF5252, borderWidth: 4}', () => { 19 | it('should have a key borderColor with #FF5252 as a value.', () => { 20 | debug._debugWithBorders('#FF5252').should.have.value('borderColor', '#FF5252'); 21 | }); 22 | 23 | it('should have a key borderWidth with 4 as a value.', () => { 24 | debug._debugWithBorders('#FF5252').should.have.value('borderWidth', 4); 25 | }); 26 | }); 27 | 28 | describe('when using the following object {color: #C6FF00, borderWidth: 4}', () => { 29 | it('should not have a key borderColor with #FF5252 as a value.', () => { 30 | debug._debugWithBorders('#C6FF00').should.not.have.value('borderColor', '#FF5252'); 31 | }); 32 | 33 | it('should not have a key borderWidth with 2 as a value.', () => { 34 | debug._debugWithBorders('#FF5252').should.not.have.value('borderWidth', 2); 35 | }); 36 | }); 37 | }); 38 | 39 | describe('debugWithBackgrounds', () => { 40 | describe('when using the following object {color: #FF5252}', () => { 41 | it('should have a key backgroundColor with #FF5252 as a value.', () => { 42 | debug._debugWithBackgrounds('#FF5252').should.have.value('backgroundColor', '#FF5252'); 43 | }); 44 | }); 45 | 46 | describe('when using the following object {color: #C6FF00, borderWidth: 4}', () => { 47 | it('should not have a key backgroundColor with #FF5252 as a value.', () => { 48 | debug._debugWithBackgrounds('#FF5252').should.not.have.value('backgroundColor', '#C6FF00'); 49 | }); 50 | }); 51 | }); 52 | 53 | describe('getColor', () => { 54 | describe('when asking for the default colors by the name', () => { 55 | Object.keys(defaultColors).map((color, key) => { 56 | let hexValue = debug._getColor(color); 57 | it(`the default ${color} color should return ${hexValue}.`, () => { 58 | debug._getColor(color).should.equal(hexValue); 59 | }); 60 | }); 61 | }); 62 | }); 63 | }); 64 | --------------------------------------------------------------------------------