Skip to content

Commit

Permalink
fix(fxFlex): apply correct flex-basis stylings
Browse files Browse the repository at this point in the history
* Fix for when flex-basis is unitless and 0
* Fix for when no width/height is applied and flex-basis should be
  set

Fixes angular#277
Fixes angular#280
Fixes angular#528
Fixes angular#534
  • Loading branch information
CaerusKaru committed Feb 25, 2018
1 parent b525771 commit a3204b2
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 32 deletions.
44 changes: 43 additions & 1 deletion src/lib/api/flexbox/flex.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,49 @@ describe('flex directive', () => {
}
});

it('should add correct styles for `fxFlex="0%"` usage', () => {
it('should add correct styles for flex-basis unitless 0 input', () => {
componentWithTemplate(`<div fxFlex="1 1 0"></div>`);

fixture.detectChanges();
expectNativeEl(fixture).toHaveStyle({
'flex': '1 1 0%',
'box-sizing': 'border-box',
}, styler);

expectNativeEl(fixture).not.toHaveStyle({
'max-width': '*'
}, styler);
});

it('should add correct styles for flex-basis 0px input', () => {
componentWithTemplate(`<div fxFlex="1 1 0px"></div>`);

fixture.detectChanges();
expectNativeEl(fixture).toHaveStyle({
'flex': '1 1 0%',
'box-sizing': 'border-box',
}, styler);

expectNativeEl(fixture).not.toHaveStyle({
'max-width': '*'
}, styler);
});

it('should add correct styles for noshrink with basis', () => {
componentWithTemplate(`<div fxFlex="1 0 50%"></div>`);

fixture.detectChanges();
expectNativeEl(fixture).toHaveStyle({
'flex': '1 0 50%',
'box-sizing': 'border-box',
}, styler);

expectNativeEl(fixture).not.toHaveStyle({
'max-width': '*'
}, styler);
});

it('should add correct styles for `fxFlex="2%"` usage', () => {
componentWithTemplate(`<div fxFlex='2%'></div>`);

fixture.detectChanges();
Expand Down
77 changes: 46 additions & 31 deletions src/lib/api/flexbox/flex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,29 @@ export class FlexDirective extends BaseFxDirective implements OnInit, OnChanges,
// The flex-direction of this element's flex container. Defaults to 'row'.
let layout = this._getFlowDirection(this.parentElement, true);
let direction = (layout.indexOf('column') > -1) ? 'column' : 'row';
let css, isValue;

let max = isFlowHorizontal(direction) ? 'max-width' : 'max-height';
let min = isFlowHorizontal(direction) ? 'min-width' : 'min-height';

let hasCalc = String(basis).indexOf('calc') > -1;
let usingCalc = hasCalc || (basis == 'auto');
let isPercent = String(basis).indexOf('%') > -1 && !hasCalc;
let hasUnits = String(basis).indexOf('px') > -1 || String(basis).indexOf('em') > -1 ||
String(basis).indexOf('vw') > -1 || String(basis).indexOf('vh') > -1;
let isPx = String(basis).indexOf('px') > -1 || usingCalc;

let isValue = (hasCalc || hasUnits);

grow = (grow == '0') ? 0 : grow;
shrink = (shrink == '0') ? 0 : shrink;

// make box inflexible when shrink and grow are both zero
// should not set a min when the grow is zero
// should not set a max when the shrink is zero
let isFixed = !grow && !shrink;

let css = {};

// flex-basis allows you to specify the initial/starting main-axis size of the element,
// before anything else is computed. It can either be a percentage or an absolute value.
// It is, however, not the breaking point for flex-grow/shrink properties
Expand All @@ -186,68 +204,65 @@ export class FlexDirective extends BaseFxDirective implements OnInit, OnChanges,
};
switch (basis || '') {
case '':
css = extendObject(clearStyles, {'flex': `${grow} ${shrink} 0.000000001px`});
basis = '0.000000001px';
break;
case 'initial': // default
case 'nogrow':
grow = 0;
css = extendObject(clearStyles, {'flex': '0 1 auto'});
basis = 'auto';
break;
case 'grow':
css = extendObject(clearStyles, {'flex': '1 1 100%'});
basis = '100%';
break;
case 'noshrink':
shrink = 0;
css = extendObject(clearStyles, {'flex': '1 0 auto'});
basis = 'auto';
break;
case 'auto':
css = extendObject(clearStyles, {'flex': `${grow} ${shrink} auto`});
break;
case 'none':
grow = 0;
shrink = 0;
css = extendObject(clearStyles, {'flex': '0 0 auto'});
basis = 'auto';
break;
default:
let hasCalc = String(basis).indexOf('calc') > -1;
let isPercent = String(basis).indexOf('%') > -1 && !hasCalc;

isValue = hasCalc ||
String(basis).indexOf('px') > -1 ||
String(basis).indexOf('em') > -1 ||
String(basis).indexOf('vw') > -1 ||
String(basis).indexOf('vh') > -1;

// Defaults to percentage sizing unless `px` is explicitly set
if (!isValue && !isPercent && !isNaN(basis as any)) {
basis = basis + '%';
}

// Fix for issue 280
if (basis === '0%') {
isValue = true;
}

if (basis === '0px') {
basis = '0%';
}

css = extendObject(clearStyles, { // fix issue #5345
'flex': `${grow} ${shrink} ${isValue ? basis : '100%'}`
});
// fix issue #5345
css = extendObject(clearStyles, {'flex': `${grow} ${shrink} ${isValue ? basis : '100%'}`});
break;
}

let max = isFlowHorizontal(direction) ? 'max-width' : 'max-height';
let min = isFlowHorizontal(direction) ? 'min-width' : 'min-height';

let usingCalc = (String(basis).indexOf('calc') > -1) || (basis == 'auto');
let isPx = String(basis).indexOf('px') > -1 || usingCalc;
if (!css['flex']) {
css = extendObject(clearStyles, {'flex': `${grow} ${shrink} ${basis}`});
}

// Fix for issues 277 and 534
// TODO(CaerusKaru): convert this to just width/height
if (basis !== '0%') {
css[min] = isFixed || (isPx && grow) ? basis : null;
css[max] = isFixed || (!usingCalc && shrink) ? basis : null;
}

// make box inflexible when shrink and grow are both zero
// should not set a min when the grow is zero
// should not set a max when the shrink is zero
let isFixed = !grow && !shrink;
css[min] = (basis == '0%') ? 0 : isFixed || (isPx && grow) ? basis : null;
css[max] = (basis == '0%') ? 0 : isFixed || (!usingCalc && shrink) ? basis : null;
// Fix for issue 528
if (!css[min] && !css[max]) {
css = extendObject(clearStyles, {
'flex': `${grow} ${shrink} ${basis}`
});
}

return extendObject(css, {'box-sizing': 'border-box'});
}

}

0 comments on commit a3204b2

Please sign in to comment.