From 52158cd42803ca369eb9c1c21757a19e947fa968 Mon Sep 17 00:00:00 2001 From: bp Date: Thu, 18 Jan 2018 17:10:18 +0530 Subject: [PATCH] feat(Popup): Provide option to handle vertical offset Completely inspired from #1146 and its comments --- src/modules/Popup/Popup.js | 34 ++++++++++----- test/specs/modules/Popup/Popup-test.js | 59 +++++++++++++++++++++++--- 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/modules/Popup/Popup.js b/src/modules/Popup/Popup.js index c62cd14acf..266f3f2e7c 100644 --- a/src/modules/Popup/Popup.js +++ b/src/modules/Popup/Popup.js @@ -72,8 +72,11 @@ export default class Popup extends Component { /** Invert the colors of the Popup. */ inverted: PropTypes.bool, - /** Horizontal offset in pixels to be applied to the Popup. */ - offset: PropTypes.number, + /** Offset in pixels to be applied to the Popup. */ + offset: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.arrayOf(PropTypes.number), + ]), /** Events triggering the popup. */ on: PropTypes.oneOfType([ @@ -135,6 +138,7 @@ export default class Popup extends Component { static defaultProps = { position: 'top left', on: 'hover', + offset: 0, } static _meta = { @@ -153,7 +157,6 @@ export default class Popup extends Component { // Do not access window/document when server side rendering if (!isBrowser()) return style - const { offset } = this.props const { pageYOffset, pageXOffset } = window const { clientWidth, clientHeight } = document.documentElement @@ -188,15 +191,26 @@ export default class Popup extends Component { } } - if (offset) { - if (_.isNumber(style.right)) { - style.right -= offset - } else { - style.left -= offset - } + return { ...style, ...this.applyOffset(style) } + } + + applyOffset = (style) => { + const { offset } = this.props + const [horizontal, vertical] = _.isNumber(offset) ? [offset, 0] : [...offset] + return { + ...this.applyHorizontalOffset(style, horizontal), + ...this.applyVeriticalOffset(style, vertical), } + } + + applyVeriticalOffset = ({ top, bottom }, offset) => { + if (_.isNumber(top)) return { bottom, top: top + offset } + return { top, bottom: bottom + offset } + } - return style + applyHorizontalOffset = ({ right, left }, offset) => { + if (_.isNumber(right)) return { left, right: right + offset } + return { right, left: left + offset } } // check if the style would display diff --git a/test/specs/modules/Popup/Popup-test.js b/test/specs/modules/Popup/Popup-test.js index 41f0950ae5..bd4a83bceb 100644 --- a/test/specs/modules/Popup/Popup-test.js +++ b/test/specs/modules/Popup/Popup-test.js @@ -79,24 +79,47 @@ describe('Popup', () => { assertInBody('.ui.popup.visible.some-class') }) - describe('offest', () => { - it('accepts an offest to the left', () => { + describe('offset', () => { + it('accepts an offset to the left', () => { wrapperMount( foo} + />, + ) + + wrapper.find('button').simulate('click') + + const rect = document.querySelector('.popup.ui').getBoundingClientRect() + const { left } = rect + + expect(left).to.be.at.least(100) + assertInBody('.ui.popup.visible') + }) + it('accepts an offset to the left', () => { + wrapperMount( + foo} />, ) wrapper.find('button').simulate('click') + + const rect = document.querySelector('.popup.ui').getBoundingClientRect() + const { left } = rect + + expect(left).to.be.at.least(100) assertInBody('.ui.popup.visible') }) - it('accepts an offest to the right', () => { + it('accepts an offset to the top', () => { wrapperMount( foo} @@ -104,6 +127,30 @@ describe('Popup', () => { ) wrapper.find('button').simulate('click') + + const rect = document.querySelector('.popup.ui').getBoundingClientRect() + const { top } = rect + + expect(top).to.be.at.least(100) + assertInBody('.ui.popup.visible') + }) + it('accepts an offset to both top and left', () => { + wrapperMount( + foo} + />, + ) + + wrapper.find('button').simulate('click') + + const rect = document.querySelector('.popup.ui').getBoundingClientRect() + const { top, left } = rect + + expect(top).to.be.at.least(100) + expect(left).to.be.at.least(100) assertInBody('.ui.popup.visible') }) })