diff --git a/packages/popper/src/utils/getBoundaries.js b/packages/popper/src/utils/getBoundaries.js index ae6583a042..6c7d3a7685 100644 --- a/packages/popper/src/utils/getBoundaries.js +++ b/packages/popper/src/utils/getBoundaries.js @@ -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; } diff --git a/packages/popper/tests/unit/getBoundaries.js b/packages/popper/tests/unit/getBoundaries.js new file mode 100644 index 0000000000..178a37031e --- /dev/null +++ b/packages/popper/tests/unit/getBoundaries.js @@ -0,0 +1,85 @@ +import getBoundaries from '../../src/utils/getBoundaries'; +import getFixedPositionOffsetParent from '../../src/utils/getFixedPositionOffsetParent'; + +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]; + } + } + } + + 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.', () => { + const result = getBoundaries(popper, node, 0, 'window', true); + expect(result.top).toBe(0); + expect(result.left).toBe(0); + expect(result.right).toBe(785); + expect(result.bottom).toBe(600); + }); + + it('returns a boundary defined by the document element by way of a child reference.', () => { + const result = getBoundaries(popper, spacing, 0, 'scrollParent', true); + expect(result.top).toBe(0); + expect(result.left).toBe(0); + expect(result.right).toBe(785); + expect(result.bottom).toBe(600); + }); + + it('returns a boundary with a null padding offset.', () => { + const result = getBoundaries(scrollingPopper, scrollingChild, 0, 'scrollParent', true); + expect(result.top).toBe(-150); + expect(result.left).toBe(-160); + expect(result.right).toBe(625); + expect(result.bottom).toBe(450); + }); +}); \ No newline at end of file diff --git a/packages/popper/tests/unit/getBoundaries.padding.js b/packages/popper/tests/unit/getBoundaries.padding.js new file mode 100644 index 0000000000..fe03a92ede --- /dev/null +++ b/packages/popper/tests/unit/getBoundaries.padding.js @@ -0,0 +1,57 @@ +import getBoundaries from '../../src/utils/getBoundaries'; +import getFixedPositionOffsetParent from '../../src/utils/getFixedPositionOffsetParent'; + +describe('utils/getBoundaries-padding-offset', () => { + let node; + + beforeEach(() => { + node = document.createElement('div'); + document.body.appendChild(node); + }); + + afterEach(() => { + document.body.removeChild(node); + }); + + it('returns a boundary with a single value padding offset.', () => { + const padding = 50; + const result = getBoundaries(null, null, padding, 'viewport', true); + expect(result.top).toBe(50); + expect(result.left).toBe(50); + expect(result.right).toBe(735); + expect(result.bottom).toBe(550); + }); + + 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); + expect(result.top).toBe(50); + expect(result.left).toBe(100); + expect(result.right).toBe(785); + expect(result.bottom).toBe(600); + }); + + 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); + expect(result.top).toBe(0); + expect(result.left).toBe(0); + expect(result.right).toBe(700); + expect(result.bottom).toBe(550); + }); + + it('returns a boundary with a null padding offset.', () => { + const padding = null; + const result = getBoundaries(null, null, padding, 'viewport', true); + expect(result.top).toBe(0); + expect(result.left).toBe(0); + expect(result.right).toBe(785); + expect(result.bottom).toBe(600); + }); +}); \ No newline at end of file diff --git a/packages/test/karma.conf.js b/packages/test/karma.conf.js index d2b6a4c65b..2e823f7551 100644 --- a/packages/test/karma.conf.js +++ b/packages/test/karma.conf.js @@ -59,8 +59,9 @@ module.exports = function(config) { '--headless', '--disable-gpu', // Without a remote debugging port, Google Chrome exits immediately. - ' --remote-debugging-port=9222', - ], + ' --remote-debugging-port=9222', + ' --window-size=802,600', + ] }, ChromeDebug: { base: 'Chrome',