diff --git a/spec/LayoutSpec.js b/spec/LayoutSpec.js index fa4f7d3f..4b01b5bf 100755 --- a/spec/LayoutSpec.js +++ b/spec/LayoutSpec.js @@ -42,6 +42,8 @@ function computeDOMLayout(node) { transfer(div, node, 'flexDirection'); transfer(div, node, 'flex'); transfer(div, node, 'justifyContent'); + transfer(div, node, 'alignSelf'); + transfer(div, node, 'alignItems'); parent.appendChild(div); (node.children || []).forEach(function(child) { renderNode(div, child); @@ -366,5 +368,69 @@ describe('Layout', function() { }); }); + it('should layout node with alignItems: flex-start', function() { + testLayout({ + style: {width: 1000, height: 1000, alignItems: 'flex-start'}, + children: [ + {style: {width: 200, height: 100}}, + {style: {width: 100, height: 100}} + ] + }, { + width: 1000, height: 1000, top: 0, left: 0, + children: [ + {width: 200, height: 100, top: 0, left: 0}, + {width: 100, height: 100, top: 100, left: 0}, + ] + }); + }); + + it('should layout node with alignItems: center', function() { + testLayout({ + style: {width: 1000, height: 1000, alignItems: 'center'}, + children: [ + {style: {width: 200, height: 100}}, + {style: {width: 100, height: 100}} + ] + }, { + width: 1000, height: 1000, top: 0, left: 0, + children: [ + {width: 200, height: 100, top: 0, left: 400}, + {width: 100, height: 100, top: 100, left: 450}, + ] + }); + }); + + it('should layout node with alignItems: flex-end', function() { + testLayout({ + style: {width: 1000, height: 1000, alignItems: 'flex-end'}, + children: [ + {style: {width: 200, height: 100}}, + {style: {width: 100, height: 100}} + ] + }, { + width: 1000, height: 1000, top: 0, left: 0, + children: [ + {width: 200, height: 100, top: 0, left: 800}, + {width: 100, height: 100, top: 100, left: 900}, + ] + }); + }); + + it('should layout node with alignSelf overrides alignItems', function() { + testLayout({ + style: {width: 1000, height: 1000, alignItems: 'flex-end'}, + children: [ + {style: {width: 200, height: 100}}, + {style: {width: 100, height: 100, alignSelf: 'center'}} + ] + }, { + width: 1000, height: 1000, top: 0, left: 0, + children: [ + {width: 200, height: 100, top: 0, left: 800}, + {width: 100, height: 100, top: 100, left: 450}, + ] + }); + }); + }); diff --git a/src/Layout.js b/src/Layout.js index 083812a0..1cc481aa 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -49,6 +49,16 @@ function computeLayout(node) { return 'flex-start'; } + function getAlignItem(node, child) { + if ('alignSelf' in child.style) { + return child.style.alignSelf; + } + if ('alignItems' in node.style) { + return node.style.alignItems; + } + return 'flex-start'; + } + var axis = { left: 'horizontal', right: 'horizontal', @@ -84,6 +94,11 @@ function computeLayout(node) { node.layout[dim[mainAxis]] = node.style[dim[mainAxis]]; } + var crossDimInStyle = dim[crossAxis] in node.style; + if (node.layout[dim[crossAxis]] === undefined && crossDimInStyle) { + node.layout[dim[crossAxis]] = node.style[dim[crossAxis]]; + } + var mainContentDim = 0; var flexibleChildrenCount = 0; children.forEach(function(child) { @@ -129,12 +144,23 @@ function computeLayout(node) { getMargin(leading[mainAxis], child) + getMargin(trailing[mainAxis], child) + betweenMainDim; + + var remainingCrossDim = node.layout[dim[crossAxis]] - child.layout[dim[crossAxis]]; + var alignItem = getAlignItem(node, child); + var leadingCrossDim = 0; + if (alignItem === 'flex-start') { + // Do nothing + } else if (alignItem === 'center') { + leadingCrossDim = remainingCrossDim / 2; + } else if (alignItem === 'flex-end') { + leadingCrossDim = remainingCrossDim; + } + child.layout[pos[crossAxis]] += leadingCrossDim; }); if (node.layout[dim[mainAxis]] === undefined && !mainDimInStyle) { node.layout[dim[mainAxis]] = mainPos; } - node.layout[dim[crossAxis]] = node.style[dim[crossAxis]]; node.layout[leading[mainAxis]] += getMargin(leading[mainAxis], node); node.layout[leading[crossAxis]] += getMargin(leading[crossAxis], node); }