Skip to content

Commit

Permalink
feat: Add specific padding to boundaries (floating-ui#518)
Browse files Browse the repository at this point in the history
  • Loading branch information
Buchheit committed Apr 25, 2018
1 parent 03f45cd commit 5f63a03
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 8 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;
}
8 changes: 4 additions & 4 deletions packages/popper/src/utils/getWindowSizes.js
Expand Up @@ -8,10 +8,10 @@ function getSize(axis, body, html, computedStyle) {
html[`offset${axis}`],
html[`scroll${axis}`],
isIE(10)
? html[`offset${axis}`] +
computedStyle[`margin${axis === 'Height' ? 'Top' : 'Left'}`] +
computedStyle[`margin${axis === 'Height' ? 'Bottom' : 'Right'}`]
: 0
? (parseInt(html[`offset${axis}`]) +
parseInt(computedStyle[`margin${axis === 'Height' ? 'Top' : 'Left'}`]) +
parseInt(computedStyle[`margin${axis === 'Height' ? 'Bottom' : 'Right'}`]))
: 0
);
}

Expand Down
109 changes: 109 additions & 0 deletions packages/popper/tests/unit/getBoundaries.js
@@ -0,0 +1,109 @@
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);

if(isIE(10) || isIE(11)) {
document.documentElement.getBoundingClientRect = () => {
return {
top: 0,
left: 0,
right: window.innerWidth,
bottom: window.innerHeight,
};
};
}
});

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

it('returns a boundary defined by the document element.', () => {
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.', () => {
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.', () => {
const result = getBoundaries(scrollingPopper, scrollingChild, 0, 'scrollParent', false);
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 5f63a03

Please sign in to comment.