Skip to content

Commit

Permalink
feat(Popup): Provide option to handle vertical offset
Browse files Browse the repository at this point in the history
        Completely inspired from Semantic-Org#1146 and its comments
  • Loading branch information
bp committed Jan 18, 2018
1 parent d077a17 commit a9e2956
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 16 deletions.
34 changes: 24 additions & 10 deletions src/modules/Popup/Popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down Expand Up @@ -135,6 +138,7 @@ export default class Popup extends Component {
static defaultProps = {
position: 'top left',
on: 'hover',
offset: 0,
}

static _meta = {
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
59 changes: 53 additions & 6 deletions test/specs/modules/Popup/Popup-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,31 +79,78 @@ 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(
<Popup
offset={50}
position='bottom right'
offset={100}
position='bottom left'
content='foo'
trigger={<button>foo</button>}
/>,
)

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(
<Popup
offset={[100, 0]}
position='bottom left'
content='foo'
trigger={<button>foo</button>}
/>,
)

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(
<Popup
offset={50}
offset={[0, 100]}
position='bottom left'
content='foo'
trigger={<button>foo</button>}
/>,
)

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(
<Popup
offset={[100, 100]}
position='bottom left'
content='foo'
trigger={<button>foo</button>}
/>,
)

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')
})
})
Expand Down

0 comments on commit a9e2956

Please sign in to comment.