Skip to content

Commit

Permalink
Merge pull request #1 from BrianBu01/floating-ui#518
Browse files Browse the repository at this point in the history
feat: Add specific padding to boundaries (floating-ui#518)
  • Loading branch information
grfullerton committed Apr 24, 2018
2 parents deb893f + efc5183 commit 00b23f4
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 4 deletions.
10 changes: 6 additions & 4 deletions packages/popper/src/utils/getBoundaries.js
Expand Up @@ -69,10 +69,12 @@ export default function getBoundaries(
}

// Add paddings
boundaries.left += padding;
boundaries.top += padding;
boundaries.right -= padding;
boundaries.bottom -= padding;
padding = padding || 0;
const isPaddingNumber = typeof padding === 'number';
boundaries.left += isPaddingNumber ? padding : padding.left || 0;
boundaries.top += isPaddingNumber ? padding : padding.top || 0;
boundaries.right -= isPaddingNumber ? padding : padding.right || 0;
boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;

return boundaries;
}
104 changes: 104 additions & 0 deletions packages/popper/tests/unit/getBoundaries.js
@@ -0,0 +1,104 @@
import getBoundaries from '../../src/utils/getBoundaries';
import isIE from '../../src/utils/isIE';

describe('utils/getBoundaries', () => {
let node;
let spacing;
let scrolling;
let scrollingChild;
let popper;
let scrollingPopper;

function setCss(element, css) {
for (const key in css) {
if (css.hasOwnProperty(key)) {
element.style[key] = css[key];
}
}
}
function expectBoundary(result, expected) {
const tolerance = 2;
expect(Math.abs(result.top - expected.top) <= tolerance).toBeTruthy();
expect(Math.abs(result.right - expected.right) <= tolerance).toBeTruthy();
expect(Math.abs(result.bottom - expected.bottom) <= tolerance).toBeTruthy();
expect(Math.abs(result.left - expected.left) <= tolerance).toBeTruthy();
}

beforeEach(() => {
node = document.createElement('div');
spacing = document.createElement('div');
popper = document.createElement('div');
scrollingPopper = document.createElement('div');

scrolling = document.createElement('div');
setCss(scrolling, {
top: '150px',
left: '160px',
right: '300px',
bottom: '400px',
height: '150px',
width: '125px',
});

scrollingChild = document.createElement('div');
setCss(scrollingChild, {
overflow: 'scroll',
top: '50px',
left: '60px',
right: '-100px',
bottom: '-200px',
height: '350px',
width: '625px',
position: 'absolute',
transform: 'translate3d(100px, 100px, 0)',
willChange: 'transform',
});

document.body.appendChild(node);
node.appendChild(spacing);
node.appendChild(scrolling);
node.appendChild(popper);
scrolling.appendChild(scrollingChild);
scrollingChild.appendChild(scrollingPopper);
});

afterEach(() => {
document.body.removeChild(node);
});

it('returns a boundary defined by the document element.', () => {
if(!isIE(10)) { //Test does not work with IE 10
const result = getBoundaries(popper, node, 0, 'window', true);
expectBoundary(result, {
top: 0,
right: window.innerWidth,
bottom: window.innerHeight,
left: 0,
});
}
});

it('returns a boundary defined by the document element by way of a child reference.', () => {
if(!isIE(10)) { //Test does not work with IE 10
const result = getBoundaries(popper, spacing, 0, 'scrollParent', true);
expectBoundary(result, {
top: 0,
right: window.innerWidth,
bottom: window.innerHeight,
left: 0,
});
}
});

it('returns a custom defined boundary within the page.', () => {
if(!isIE(10) && !isIE(11)) { //Test does not work with IE 10 or IE 11
const result = getBoundaries(scrollingPopper, scrollingChild, 0, 'scrollParent', true);
expectBoundary(result, {
top: -150,
right: window.innerWidth - 160,
bottom: window.innerHeight - 150,
left: -160,
});
}
});
});
72 changes: 72 additions & 0 deletions packages/popper/tests/unit/getBoundaries.padding.js
@@ -0,0 +1,72 @@
import getBoundaries from '../../src/utils/getBoundaries';

describe('utils/getBoundaries-padding-offset', () => {
let node;

beforeEach(() => {
node = document.createElement('div');
document.body.appendChild(node);
});

afterEach(() => {
document.body.removeChild(node);
});

function expectBoundary(result, expected) {
const tolerance = 2;
expect(Math.abs(result.top - expected.top) <= tolerance).toBeTruthy();
expect(Math.abs(result.right - expected.right) <= tolerance).toBeTruthy();
expect(Math.abs(result.bottom - expected.bottom) <= tolerance).toBeTruthy();
expect(Math.abs(result.left - expected.left) <= tolerance).toBeTruthy();
}

it('returns a boundary with a single value padding offset.', () => {
const padding = 50;
const result = getBoundaries(null, null, padding, 'viewport', true);
expectBoundary(result, {
top: 50,
right: window.innerWidth - 50,
bottom: window.innerHeight - 50,
left: 50,
});
});

it('returns a boundary with a top and left componentized padding offset.', () => {
const padding = {
top: 50,
left: 100,
};
const result = getBoundaries(null, null, padding, 'viewport', true);
expectBoundary(result, {
top: 50,
right: window.innerWidth,
bottom: window.innerHeight,
left: 100,
});
});

it('returns a boundary with a bottom and right componentized padding offset.', () => {
const padding = {
bottom: 50,
right: 85,
};
const result = getBoundaries(null, null, padding, 'viewport', true);
expectBoundary(result, {
top: 0,
right: window.innerWidth - 85,
bottom: window.innerHeight - 50,
left: 0,
});
});

it('returns a boundary with a null padding offset.', () => {
const padding = null;
const result = getBoundaries(null, null, padding, 'viewport', true);
expectBoundary(result, {
top: 0,
right: window.innerWidth,
bottom: window.innerHeight,
left: 0,
});
});
});

0 comments on commit 00b23f4

Please sign in to comment.