From 8a3f516a9ed0e2c9d6f881ee59b2705dec2ffa22 Mon Sep 17 00:00:00 2001 From: abdallahm Date: Thu, 28 Jul 2016 01:05:02 +0200 Subject: [PATCH 1/8] Idea for orientation change support #9 --- README.md | 7 +++++++ src/api.js | 13 +++++++++++++ src/replacers/media-queries.js | 4 ++-- src/replacers/percent.js | 8 ++++---- src/sheet.js | 1 + src/utils.js | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2df70b8..dcec738 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,13 @@ const styles = EStyleSheet.create({ } }); ``` + +For the orientation change: +``` +styles = EStyleSheet.orientationUpdate(orientation, styles); +this.forceUpdate(); +``` + See full example [here](examples/media-queries). \[[top](#)\] diff --git a/src/api.js b/src/api.js index 9bab280..ea69721 100644 --- a/src/api.js +++ b/src/api.js @@ -40,6 +40,19 @@ export default class { return sheet.getResult(); } + /** + * Updates a specific stylesheet when the orientation changes + * @param {orientation} string + * @param {originalObj} obj + * @returns {Object} + */ + orientationUpdate(orientation, originalObj) { + window.orientation = orientation; + let sheet = new Sheet(originalObj.source); + sheet.calc(this.globalVars); + return sheet.getResult(); + } + /** * Builds all created stylesheets with passed variables * @param {Object} [gVars] diff --git a/src/replacers/media-queries.js b/src/replacers/media-queries.js index 4b0d1c1..bec8aef 100644 --- a/src/replacers/media-queries.js +++ b/src/replacers/media-queries.js @@ -64,11 +64,11 @@ function process(obj) { * @returns {Object} */ function getMatchObject() { - const win = Dimensions.get('window'); + const win = utils.calcOrientation(window.orientation); return { width: win.width, height: win.height, - orientation: win.width > win.height ? 'landscape' : 'portrait', + orientation: win.orientation, 'aspect-ratio': win.width / win.height, type: Platform.OS, }; diff --git a/src/replacers/percent.js b/src/replacers/percent.js index d070a44..d58ffef 100644 --- a/src/replacers/percent.js +++ b/src/replacers/percent.js @@ -1,10 +1,8 @@ /** * Calculation of percent strings */ +import utils from '../utils'; -import {Dimensions} from 'react-native'; - -const {width, height} = Dimensions.get('window'); const V_PROPS = [ 'height', 'top', @@ -44,8 +42,10 @@ function isPercent(str) { * @returns {number} */ function calc(str, prop) { + const win = utils.calcOrientation(window.orientation);; + let percent = parseInt(str.substring(0, str.length - 1), 10); - let base = isVertical(prop) ? height : width; + let base = isVertical(prop) ? win.height : win.width; return base * percent / 100; } diff --git a/src/sheet.js b/src/sheet.js index e1ffa9f..256d59e 100644 --- a/src/sheet.js +++ b/src/sheet.js @@ -32,6 +32,7 @@ export default class { processSource() { this.processedSource = mediaQueries.process(this.source); + this.result.source = this.source; } calcVars(inVars) { diff --git a/src/utils.js b/src/utils.js index e4d59ff..18ccbda 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,10 +1,12 @@ /** * Utils */ +import {Dimensions} from 'react-native'; export default { excludeKeys, isObject, + calcOrientation }; /** @@ -31,3 +33,33 @@ function excludeKeys(obj, keys) { function isObject(obj) { return typeof obj === 'object' && obj !== null; } + +function calcOrientation(orientation){ + var {width, height} = Dimensions.get('window'); + + if(orientation){ + orientation = orientation.toLowerCase(); + }else{ + + } + + var newWidth = width; + var newHeight = height; + + if (orientation == 'landscape') { + if(height > width){ + var newWidth = height; + var newHeight = width; + } + }else if (orientation == 'portrait') { + if(width > height){ + var newWidth = height; + var newHeight = width; + } + } + + if(!orientation){ + orientation = newWidth > newHeight ? 'landscape' : 'portrait' + } + return {width: newWidth, height: newHeight, orientation: orientation}; +} \ No newline at end of file From 0f8277f315e4d0216852c6eddf3ba17acd17135f Mon Sep 17 00:00:00 2001 From: Abdallah Mohsen Date: Thu, 28 Jul 2016 01:07:40 +0200 Subject: [PATCH 2/8] Update utils.js --- src/utils.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/utils.js b/src/utils.js index 18ccbda..f7215ec 100644 --- a/src/utils.js +++ b/src/utils.js @@ -36,13 +36,9 @@ function isObject(obj) { function calcOrientation(orientation){ var {width, height} = Dimensions.get('window'); - if(orientation){ orientation = orientation.toLowerCase(); - }else{ - } - var newWidth = width; var newHeight = height; @@ -57,9 +53,8 @@ function calcOrientation(orientation){ var newHeight = width; } } - if(!orientation){ orientation = newWidth > newHeight ? 'landscape' : 'portrait' } return {width: newWidth, height: newHeight, orientation: orientation}; -} \ No newline at end of file +} From 804541225762d96e172e92558a7a12d3dc9e4d84 Mon Sep 17 00:00:00 2001 From: Abdallah Mohsen Date: Thu, 28 Jul 2016 01:14:52 +0200 Subject: [PATCH 3/8] Update README.md --- README.md | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dcec738..ea24761 100644 --- a/README.md +++ b/README.md @@ -264,10 +264,40 @@ const styles = EStyleSheet.create({ }); ``` -For the orientation change: +An idea for the orientation change support, it requires using another package for detecting the orientation change event, like react-native-orientation + +```js +var Orientation = require('react-native-orientation'); +var styles = EStyleSheet.create({ + card: { + height: 200, + }, + '@media all and (orientation: portrait)': { + card: { + width: '42%' + } + }, + '@media all and (orientation: landscape)': { + card: { + width: '23%' + } + } +}); ``` -styles = EStyleSheet.orientationUpdate(orientation, styles); -this.forceUpdate(); +inside your component use: +```js +componentDidMount() { + Orientation.addOrientationListener(this._orientationDidChange.bind(this)); +} + +componentWillUnmount() { + Orientation.removeOrientationListener(this._orientationDidChange); +} + +_orientationDidChange(orientation) { + styles = EStyleSheet.orientationUpdate(orientation, styles); + this.forceUpdate(); +} ``` See full example [here](examples/media-queries). From 12908f3fdcad94cb3868bc8a8fc03a0b4b11c489 Mon Sep 17 00:00:00 2001 From: abdallahm Date: Thu, 28 Jul 2016 21:25:38 +0200 Subject: [PATCH 4/8] remove source key from sheet and cache it --- src/api.js | 18 +++++++++++++++++- src/sheet.js | 1 - 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/api.js b/src/api.js index ea69721..9939786 100644 --- a/src/api.js +++ b/src/api.js @@ -37,6 +37,8 @@ export default class { } else { this.sheets.push(sheet); } + this._cacheSheetSource(sheet.getResult(), sheet); + return sheet.getResult(); } @@ -48,7 +50,8 @@ export default class { */ orientationUpdate(orientation, originalObj) { window.orientation = orientation; - let sheet = new Sheet(originalObj.source); + var source = this._cacheSheetSource(originalObj); + let sheet = new Sheet(source); sheet.calc(this.globalVars); return sheet.getResult(); } @@ -112,4 +115,17 @@ export default class { this.listeners[event].forEach(listener => listener()); } } + + _cacheSheetSource(key, sheet){ + key = JSON.stringify(Object.keys(key)); + if (!memoize.cache) { + memoize.cache = {}; + } + if (!memoize.cache[key]) { + if(sheet){ + memoize.cache[key] = sheet.source; + } + } + return memoize.cache[key]; + } } diff --git a/src/sheet.js b/src/sheet.js index 256d59e..e1ffa9f 100644 --- a/src/sheet.js +++ b/src/sheet.js @@ -32,7 +32,6 @@ export default class { processSource() { this.processedSource = mediaQueries.process(this.source); - this.result.source = this.source; } calcVars(inVars) { From 55df5adf77f759d2d84f13edf241a48ae9a8a24a Mon Sep 17 00:00:00 2001 From: abdallahm Date: Thu, 28 Jul 2016 22:02:35 +0200 Subject: [PATCH 5/8] add test case for orientation change --- src/__tests__/api.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/__tests__/api.test.js b/src/__tests__/api.test.js index 8713985..7f0d02c 100644 --- a/src/__tests__/api.test.js +++ b/src/__tests__/api.test.js @@ -120,4 +120,19 @@ describe('EStyleSheet API', function () { const fn = () => api.subscribe('build', null); expect(fn).toThrowError('Listener should be a function.'); }); + + it('should update styles in orientation change', function () { + api.build({}); + let defaultStyles = api.create({ + card: { + width: '50%', + } + }); + + let portraitStyles = api.orientationUpdate('portrait', defaultStyles); + expect(defaultStyles).toEqual(portraitStyles); + + let landscapeStyles = api.orientationUpdate('landscape', defaultStyles); + expect(defaultStyles).not.toEqual(landscapeStyles); + }); }); From 83a7f0cfb8e8fb218ec6956f2596089d37466153 Mon Sep 17 00:00:00 2001 From: abdallahm Date: Thu, 28 Jul 2016 22:29:45 +0200 Subject: [PATCH 6/8] fix code issues --- .eslintrc | 4 ++++ src/api.js | 2 +- src/replacers/media-queries.js | 2 +- src/replacers/percent.js | 2 +- src/utils.js | 8 ++++---- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.eslintrc b/.eslintrc index 9a5dac9..ff5e25c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -14,6 +14,10 @@ "node": true, "jest": true }, + + "globals": { + "window": true + }, "plugins": [ "react", diff --git a/src/api.js b/src/api.js index 9939786..d4a749d 100644 --- a/src/api.js +++ b/src/api.js @@ -50,7 +50,7 @@ export default class { */ orientationUpdate(orientation, originalObj) { window.orientation = orientation; - var source = this._cacheSheetSource(originalObj); + var source = this._cacheSheetSource(originalObj); let sheet = new Sheet(source); sheet.calc(this.globalVars); return sheet.getResult(); diff --git a/src/replacers/media-queries.js b/src/replacers/media-queries.js index bec8aef..089e817 100644 --- a/src/replacers/media-queries.js +++ b/src/replacers/media-queries.js @@ -8,7 +8,7 @@ * - aspect-ratio */ -import {Dimensions, Platform} from 'react-native'; +import {Platform} from 'react-native'; import mediaQuery from 'css-mediaquery'; import utils from '../utils'; diff --git a/src/replacers/percent.js b/src/replacers/percent.js index d58ffef..5ee36d2 100644 --- a/src/replacers/percent.js +++ b/src/replacers/percent.js @@ -42,7 +42,7 @@ function isPercent(str) { * @returns {number} */ function calc(str, prop) { - const win = utils.calcOrientation(window.orientation);; + const win = utils.calcOrientation(window.orientation); let percent = parseInt(str.substring(0, str.length - 1), 10); let base = isVertical(prop) ? win.height : win.width; diff --git a/src/utils.js b/src/utils.js index f7215ec..0bee06d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -44,13 +44,13 @@ function calcOrientation(orientation){ if (orientation == 'landscape') { if(height > width){ - var newWidth = height; - var newHeight = width; + newWidth = height; + newHeight = width; } }else if (orientation == 'portrait') { if(width > height){ - var newWidth = height; - var newHeight = width; + newWidth = height; + newHeight = width; } } if(!orientation){ From f1d672afe9081b4086eb429daad3b2b8ebde3af0 Mon Sep 17 00:00:00 2001 From: abdallahm Date: Wed, 10 Aug 2016 21:22:34 +0200 Subject: [PATCH 7/8] listen to onLayout event --- src/__tests__/api.test.js | 11 ++++++--- src/api.js | 10 +++++--- src/replacers/media-queries.js | 2 +- src/replacers/percent.js | 3 +-- src/utils.js | 42 +++++++++++++++++----------------- 5 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/__tests__/api.test.js b/src/__tests__/api.test.js index 7f0d02c..de5bfdb 100644 --- a/src/__tests__/api.test.js +++ b/src/__tests__/api.test.js @@ -129,10 +129,15 @@ describe('EStyleSheet API', function () { } }); - let portraitStyles = api.orientationUpdate('portrait', defaultStyles); + var layout = {nativeEvent:{layout:{width:50, height: 100}}}; + let landscapeStyles = api.orientationUpdate(layout, defaultStyles); + expect(defaultStyles).not.toEqual(landscapeStyles); + + layout = {nativeEvent:{layout:{width:100, height: 50}}}; + let portraitStyles = api.orientationUpdate(layout, defaultStyles); expect(defaultStyles).toEqual(portraitStyles); - let landscapeStyles = api.orientationUpdate('landscape', defaultStyles); - expect(defaultStyles).not.toEqual(landscapeStyles); + let portraitStyles2 = api.orientationUpdate(layout, landscapeStyles); + expect(portraitStyles2).toEqual(false); }); }); diff --git a/src/api.js b/src/api.js index d4a749d..f5064f0 100644 --- a/src/api.js +++ b/src/api.js @@ -8,6 +8,8 @@ import Value from './value'; import vars from './replacers/vars'; import memoize from './memoize'; import child from './child'; +import utils from './utils'; + const BUILD_EVENT = 'build'; @@ -48,14 +50,16 @@ export default class { * @param {originalObj} obj * @returns {Object} */ - orientationUpdate(orientation, originalObj) { - window.orientation = orientation; + orientationUpdate(event, originalObj) { + var dimensions = utils.setDimensions(event.nativeEvent.layout); + if(dimensions.updated == false){ + return false; + } var source = this._cacheSheetSource(originalObj); let sheet = new Sheet(source); sheet.calc(this.globalVars); return sheet.getResult(); } - /** * Builds all created stylesheets with passed variables * @param {Object} [gVars] diff --git a/src/replacers/media-queries.js b/src/replacers/media-queries.js index 089e817..5d68746 100644 --- a/src/replacers/media-queries.js +++ b/src/replacers/media-queries.js @@ -64,7 +64,7 @@ function process(obj) { * @returns {Object} */ function getMatchObject() { - const win = utils.calcOrientation(window.orientation); + const win = utils.getDimensions(); return { width: win.width, height: win.height, diff --git a/src/replacers/percent.js b/src/replacers/percent.js index 5ee36d2..40afb84 100644 --- a/src/replacers/percent.js +++ b/src/replacers/percent.js @@ -42,8 +42,7 @@ function isPercent(str) { * @returns {number} */ function calc(str, prop) { - const win = utils.calcOrientation(window.orientation); - + const win = utils.getDimensions(); let percent = parseInt(str.substring(0, str.length - 1), 10); let base = isVertical(prop) ? win.height : win.width; return base * percent / 100; diff --git a/src/utils.js b/src/utils.js index 0bee06d..b0f3dd2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -6,7 +6,8 @@ import {Dimensions} from 'react-native'; export default { excludeKeys, isObject, - calcOrientation + setDimensions, + getDimensions }; /** @@ -34,27 +35,26 @@ function isObject(obj) { return typeof obj === 'object' && obj !== null; } -function calcOrientation(orientation){ - var {width, height} = Dimensions.get('window'); - if(orientation){ - orientation = orientation.toLowerCase(); - } - var newWidth = width; - var newHeight = height; - - if (orientation == 'landscape') { - if(height > width){ - newWidth = height; - newHeight = width; - } - }else if (orientation == 'portrait') { - if(width > height){ - newWidth = height; - newHeight = width; +function setDimensions(layout, defaultLayout){ + defaultLayout = defaultLayout || false; + var updated = false; + if(!defaultLayout){ + if(window.dimensions.width !== layout.width){ + updated = true; } } - if(!orientation){ - orientation = newWidth > newHeight ? 'landscape' : 'portrait' + return window.dimensions = { + orientation: (layout.width < layout.height ? 'portrait' : 'landscape'), + width: layout.width, + height: layout.height, + default: defaultLayout, + updated: updated + } +} + +function getDimensions(){ + if(!window.dimensions){ + setDimensions(Dimensions.get('window'), true); } - return {width: newWidth, height: newHeight, orientation: orientation}; + return window.dimensions; } From 32cd54409645b6237eeb32a5ae10b09a79a87fa1 Mon Sep 17 00:00:00 2001 From: abdallahm Date: Wed, 10 Aug 2016 21:29:02 +0200 Subject: [PATCH 8/8] add an example of usage for orientation change --- README.md | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ea24761..efa25d2 100644 --- a/README.md +++ b/README.md @@ -264,13 +264,13 @@ const styles = EStyleSheet.create({ }); ``` -An idea for the orientation change support, it requires using another package for detecting the orientation change event, like react-native-orientation +Here is an example of the orientation change: ```js -var Orientation = require('react-native-orientation'); var styles = EStyleSheet.create({ card: { height: 200, + backgroundColor: 'green' }, '@media all and (orientation: portrait)': { card: { @@ -283,20 +283,22 @@ var styles = EStyleSheet.create({ } } }); -``` -inside your component use: -```js -componentDidMount() { - Orientation.addOrientationListener(this._orientationDidChange.bind(this)); -} - -componentWillUnmount() { - Orientation.removeOrientationListener(this._orientationDidChange); -} -_orientationDidChange(orientation) { - styles = EStyleSheet.orientationUpdate(orientation, styles); - this.forceUpdate(); +class example extends React.Component { + onLayoutChange(event){ + var updatedStyles = EStyleSheet.orientationUpdate(event, styles); + if(updatedStyles){ + styles = updatedStyles; + this.forceUpdate(); + } + } + + render() { + console.warn('render'); + return ( + ... + ) + } } ```