Permalink
Browse files

Add percentage support to react native

Summary:
Adds support for percentage value in react native.

syntax: property: 100 | property | '100%'

supported properties:
padding
margin
width
height
minWidth
minHeight
maxWidth
maxHeight
flexBasis

```
class Playground extends React.Component {
  render() {
    return (
      <View style={{backgroundColor: 'white', padding: 10, paddingTop: 30, height: '100%'}}>
        <Text>
          If you want to quickly test out something,
          open the Playground.js file and start coding.
        </Text>
        <View style={{backgroundColor: 'red', height: 50, width: 50}}/>
        <View style={{backgroundColor: 'blue', height: '50%', width: '50%'}}/>
      </View>
    );
  }
}
```

Reviewed By: astreet

Differential Revision: D4376549

fbshipit-source-id: c41d68a7555396f95d063a7527ee081773ac56dc
  • Loading branch information...
emilsjolander authored and facebook-github-bot committed Jan 11, 2017
1 parent 00d5674 commit 3f49e743bea730907066677c7cbfbb1260677d11
@@ -0,0 +1,46 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* 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 NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK 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.
*/
#import <XCTest/XCTest.h>
#import <React/RCTConvert.h>
#import <React/RCTUtils.h>
@interface RCTConvert_YGValueTests : XCTestCase
@end
@implementation RCTConvert_YGValueTests
- (void)testUndefined
{
YGValue value = [RCTConvert YGValue:nil];
XCTAssertEqual(value.unit, YGUnitUndefined);
}
- (void)testNumberPoints
{
YGValue value = [RCTConvert YGValue:@100];
XCTAssertEqual(value.unit, YGUnitPixel);
XCTAssertEqual(value.value, 100);
}
- (void)testStringPercent
{
YGValue value = [RCTConvert YGValue:@"100%"];
XCTAssertEqual(value.unit, YGUnitPercent);
XCTAssertEqual(value.value, 100);
}
@end
@@ -30,184 +30,256 @@ var LayoutPropTypes = {
/** `width` sets the width of this component.
*
* It works similarly to `width` in CSS, but in React Native you
* must use logical pixel units, rather than percents, ems, or any of that.
* must use points or percentages. Ems and other units are not supported.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/width for more details.
*/
width: ReactPropTypes.number,
width: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `height` sets the height of this component.
*
* It works similarly to `height` in CSS, but in React Native you
* must use logical pixel units, rather than percents, ems, or any of that.
* must use points or percentages. Ems and other units are not supported.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/height for more details.
*/
height: ReactPropTypes.number,
height: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `top` is the number of logical pixels to offset the top edge of
* this component.
*
* It works similarly to `top` in CSS, but in React Native you must
* use logical pixel units, rather than percents, ems, or any of that.
* It works similarly to `top` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/top
* for more details of how `top` affects layout.
*/
top: ReactPropTypes.number,
top: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `left` is the number of logical pixels to offset the left edge of
* this component.
*
* It works similarly to `left` in CSS, but in React Native you must
* use logical pixel units, rather than percents, ems, or any of that.
* It works similarly to `left` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/left
* for more details of how `left` affects layout.
*/
left: ReactPropTypes.number,
left: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `right` is the number of logical pixels to offset the right edge of
* this component.
*
* It works similarly to `right` in CSS, but in React Native you must
* use logical pixel units, rather than percents, ems, or any of that.
* It works similarly to `right` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/right
* for more details of how `right` affects layout.
*/
right: ReactPropTypes.number,
right: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `bottom` is the number of logical pixels to offset the bottom edge of
* this component.
*
* It works similarly to `bottom` in CSS, but in React Native you must
* use logical pixel units, rather than percents, ems, or any of that.
* It works similarly to `bottom` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/bottom
* for more details of how `bottom` affects layout.
*/
bottom: ReactPropTypes.number,
bottom: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `minWidth` is the minimum width for this component, in logical pixels.
*
* It works similarly to `min-width` in CSS, but in React Native you
* must use logical pixel units, rather than percents, ems, or any of that.
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/min-width
* for more details.
*/
minWidth: ReactPropTypes.number,
minWidth: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `maxWidth` is the maximum width for this component, in logical pixels.
*
* It works similarly to `max-width` in CSS, but in React Native you
* must use logical pixel units, rather than percents, ems, or any of that.
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/max-width
* for more details.
*/
maxWidth: ReactPropTypes.number,
maxWidth: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `minHeight` is the minimum height for this component, in logical pixels.
*
* It works similarly to `min-height` in CSS, but in React Native you
* must use logical pixel units, rather than percents, ems, or any of that.
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/min-height
* for more details.
*/
minHeight: ReactPropTypes.number,
minHeight: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `maxHeight` is the maximum height for this component, in logical pixels.
*
* It works similarly to `max-height` in CSS, but in React Native you
* must use logical pixel units, rather than percents, ems, or any of that.
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/max-height
* for more details.
*/
maxHeight: ReactPropTypes.number,
maxHeight: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** Setting `margin` has the same effect as setting each of
* `marginTop`, `marginLeft`, `marginBottom`, and `marginRight`.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/margin
* for more details.
*/
margin: ReactPropTypes.number,
margin: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** Setting `marginVertical` has the same effect as setting both
* `marginTop` and `marginBottom`.
*/
marginVertical: ReactPropTypes.number,
marginVertical: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** Setting `marginHorizontal` has the same effect as setting
* both `marginLeft` and `marginRight`.
*/
marginHorizontal: ReactPropTypes.number,
marginHorizontal: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `marginTop` works like `margin-top` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-top
* for more details.
*/
marginTop: ReactPropTypes.number,
marginTop: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `marginBottom` works like `margin-bottom` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-bottom
* for more details.
*/
marginBottom: ReactPropTypes.number,
marginBottom: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `marginLeft` works like `margin-left` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-left
* for more details.
*/
marginLeft: ReactPropTypes.number,
marginLeft: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `marginRight` works like `margin-right` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-right
* for more details.
*/
marginRight: ReactPropTypes.number,
marginRight: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** Setting `padding` has the same effect as setting each of
* `paddingTop`, `paddingBottom`, `paddingLeft`, and `paddingRight`.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/padding
* for more details.
*/
padding: ReactPropTypes.number,
padding: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** Setting `paddingVertical` is like setting both of
* `paddingTop` and `paddingBottom`.
*/
paddingVertical: ReactPropTypes.number,
paddingVertical: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** Setting `paddingHorizontal` is like setting both of
* `paddingLeft` and `paddingRight`.
*/
paddingHorizontal: ReactPropTypes.number,
paddingHorizontal: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `paddingTop` works like `padding-top` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-top
* for more details.
*/
paddingTop: ReactPropTypes.number,
paddingTop: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `paddingBottom` works like `padding-bottom` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-bottom
* for more details.
*/
paddingBottom: ReactPropTypes.number,
paddingBottom: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `paddingLeft` works like `padding-left` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-left
* for more details.
*/
paddingLeft: ReactPropTypes.number,
paddingLeft: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `paddingRight` works like `padding-right` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-right
* for more details.
*/
paddingRight: ReactPropTypes.number,
paddingRight: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/** `borderWidth` works like `border-width` in CSS.
* See https://developer.mozilla.org/en-US/docs/Web/CSS/border-width
@@ -365,7 +437,10 @@ var LayoutPropTypes = {
flex: ReactPropTypes.number,
flexGrow: ReactPropTypes.number,
flexShrink: ReactPropTypes.number,
flexBasis: ReactPropTypes.number,
flexBasis: ReactPropTypes.oneOfType([
ReactPropTypes.number,
ReactPropTypes.string,
]),
/**
* Aspect ratio control the size of the undefined dimension of a node. Aspect ratio is a
View
@@ -10,13 +10,13 @@
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import <yoga/Yoga.h>
#import <React/RCTAnimationType.h>
#import <React/RCTBorderStyle.h>
#import <React/RCTDefines.h>
#import <React/RCTLog.h>
#import <React/RCTPointerEvents.h>
#import <React/RCTTextDecorationLineType.h>
#import <yoga/Yoga.h>
/**
* This class provides a collection of conversion functions for mapping
@@ -90,6 +90,8 @@ typedef NSURL RCTFileURL;
+ (UIColor *)UIColor:(id)json;
+ (CGColorRef)CGColor:(id)json CF_RETURNS_NOT_RETAINED;
+ (YGValue)YGValue:(id)json;
+ (NSArray<NSArray *> *)NSArrayArray:(id)json;
+ (NSArray<NSString *> *)NSStringArray:(id)json;
+ (NSArray<NSArray<NSString *> *> *)NSStringArrayArray:(id)json;
Oops, something went wrong.

13 comments on commit 3f49e74

@ahmetabdi

This comment has been minimized.

Show comment
Hide comment
@ahmetabdi

ahmetabdi replied Jan 13, 2017

Nice work

@henrikra

This comment has been minimized.

Show comment
Hide comment
@henrikra

henrikra Feb 10, 2017

@emilsjolander Can these values be animated with Animated? :O

henrikra replied Feb 10, 2017

@emilsjolander Can these values be animated with Animated? :O

@fragno

This comment has been minimized.

Show comment
Hide comment
@fragno

fragno Feb 11, 2017

amazing work

fragno replied Feb 11, 2017

amazing work

@emilsjolander

This comment has been minimized.

Show comment
Hide comment
@emilsjolander

emilsjolander Feb 11, 2017

Contributor

@henrikra i dont see why not. May need some changes in RN though

Contributor

emilsjolander replied Feb 11, 2017

@henrikra i dont see why not. May need some changes in RN though

@henrikra

This comment has been minimized.

Show comment
Hide comment
@henrikra

henrikra Feb 11, 2017

@emilsjolander Maybe you should try and add example to the docs? Since this changes so many things

henrikra replied Feb 11, 2017

@emilsjolander Maybe you should try and add example to the docs? Since this changes so many things

@emilsjolander

This comment has been minimized.

Show comment
Hide comment
@emilsjolander

emilsjolander Feb 11, 2017

Contributor

@henrikra i know this is on the todo list for RN. Feel free to help us out with doc PRs :)

Contributor

emilsjolander replied Feb 11, 2017

@henrikra i know this is on the todo list for RN. Feel free to help us out with doc PRs :)

@henrikra

This comment has been minimized.

Show comment
Hide comment
@henrikra

henrikra Mar 2, 2017

@emilsjolander I tried this today and it worked nicely with width and height. When I tried like left: 50% it did not work like expected. I am sure you know this already though :D

henrikra replied Mar 2, 2017

@emilsjolander I tried this today and it worked nicely with width and height. When I tried like left: 50% it did not work like expected. I am sure you know this already though :D

@emilsjolander

This comment has been minimized.

Show comment
Hide comment
@emilsjolander

emilsjolander Mar 2, 2017

Contributor

I did not. Please file an issue over at facebook/yoga

Contributor

emilsjolander replied Mar 2, 2017

I did not. Please file an issue over at facebook/yoga

@henrikra

This comment has been minimized.

Show comment
Hide comment
@henrikra

henrikra Mar 2, 2017

@emilsjolander Look like it has to do something with flexDirection: 'row'. Here is the issue I did: #12660 :) Tell me if you need more info.

henrikra replied Mar 2, 2017

@emilsjolander Look like it has to do something with flexDirection: 'row'. Here is the issue I did: #12660 :) Tell me if you need more info.

@KonstantinShkut

This comment has been minimized.

Show comment
Hide comment
@KonstantinShkut

KonstantinShkut Mar 10, 2017

I can't believe it's happening 😱 Great job @emilsjolander !!!

KonstantinShkut replied Mar 10, 2017

I can't believe it's happening 😱 Great job @emilsjolander !!!

@clemerjr

This comment has been minimized.

Show comment
Hide comment
@clemerjr

clemerjr Dec 22, 2017

@emilsjolander I am trying to use this on Android, with react-native v0.51.0 and got this error:
Error while updating property 'width' in shadow node of type: RCTViewnullInvalid float: "90%"

On iOS its working normally. I will open an issue ticket.

Thanks for this feature

clemerjr replied Dec 22, 2017

@emilsjolander I am trying to use this on Android, with react-native v0.51.0 and got this error:
Error while updating property 'width' in shadow node of type: RCTViewnullInvalid float: "90%"

On iOS its working normally. I will open an issue ticket.

Thanks for this feature

@t-benze

This comment has been minimized.

Show comment
Hide comment
@t-benze

t-benze Jan 22, 2018

This is awesome! One question, any reason this is not documented yet? is it ready to use in production?

t-benze replied Jan 22, 2018

This is awesome! One question, any reason this is not documented yet? is it ready to use in production?

@emilioicai

This comment has been minimized.

Show comment
Hide comment
@emilioicai

emilioicai Sep 17, 2018

Contributor

This feature is really nice but the fact it remains undocumented for so long prevents me from using it on production

Contributor

emilioicai replied Sep 17, 2018

This feature is really nice but the fact it remains undocumented for so long prevents me from using it on production

Please sign in to comment.