e.stopPropagation()}
- onTouchEnd={(e) => e.stopPropagation()}
- >
-
-
- {header}
-
-
- {body}
+class Modal extends React.Component {
+ handleScrollAndEscKeys = (e) => {
+ if (scrollKeys[e.keyCode]) {
+ preventDefault(e)
+ return false
+ } else if (e.keyCode === keycode('esc')) {
+ this.props.toggle(false)
+ }
+ }
+
+ disableScroll () {
+ window.addEventListener('DOMMouseScroll', preventDefault, false)
+ window.addEventListener('wheel', preventDefault, false)
+ window.addEventListener('touchmove', preventDefault, false)
+ window.addEventListener('keydown', this.handleScrollAndEscKeys, false)
+ }
+
+ enableScroll () {
+ window.removeEventListener('DOMMouseScroll', preventDefault, false)
+ window.removeEventListener('wheel', preventDefault, false)
+ window.removeEventListener('touchmove', preventDefault, false)
+ window.removeEventListener('keydown', this.handleScrollAndEscKeys, false)
+ }
+
+ componentWillReceiveProps (props) {
+ if (props.visible && !this.props.visible) {
+ document.activeElement.blur()
+ this.disableScroll()
+ } else if (!props.visible && this.props.visible) {
+ this.enableScroll()
+ }
+ }
+
+ render () {
+ const {header, body, footer, visible, toggle} = this.props
+ return (
+
{
+ e.preventDefault()
+ e.stopPropagation()
+ toggle(false)
+ }}
+ >
+
e.stopPropagation()}
+ onTouchEnd={(e) => e.stopPropagation()}
+ >
+
+
+ {header}
+
+
+ {body}
+
+
+
+ {footer}
+
-
- {footer}
-
-
-
-)
+ )
+ }
+}
Modal.propTypes = {
header: PropTypes.element,
diff --git a/src/js/modal/test/test.js b/src/js/modal/test/test.js
index 76f3d9a6c..c6a8bd3b6 100644
--- a/src/js/modal/test/test.js
+++ b/src/js/modal/test/test.js
@@ -2,7 +2,7 @@
import assert from 'assert'
import React from 'react'
-import Modal from '../'
+import {default as Modal, preventDefault} from '../'
import {mount} from 'enzyme'
describe('Modal', () => {
@@ -26,15 +26,6 @@ describe('Modal', () => {
wrapper.find('.mdc-Modal-overlay').simulate('click')
})
- it('should callback when touching dark background', (done) => {
- const callback = (visible) => {
- assert.equal(visible, false)
- done()
- }
- const wrapper = mount(
)
- wrapper.find('.mdc-Modal-overlay').simulate('touchend')
- })
-
it('should have a custom header', () => {
const header =
my custom header
const wrapper = mount(
)
@@ -52,4 +43,161 @@ describe('Modal', () => {
const wrapper = mount(
)
assert.equal(wrapper.find('.mdc-Modal-footer').text(), 'my custom footer')
})
+
+ it('.disableScroll() should replace window event listeners with preventDefault', () => {
+ const wrapper = mount(
)
+ const calls = []
+ const addEventListenerBak = window.addEventListener
+ window.addEventListener = (type, dispatch, flag) => {
+ calls.push({
+ type,
+ dispatch,
+ flag
+ })
+ }
+ wrapper.instance().disableScroll()
+ assert.deepEqual(calls[0], {
+ type: 'DOMMouseScroll',
+ dispatch: preventDefault,
+ flag: false
+ })
+ assert.deepEqual(calls[1], {
+ type: 'wheel',
+ dispatch: preventDefault,
+ flag: false
+ })
+ assert.deepEqual(calls[2], {
+ type: 'touchmove',
+ dispatch: preventDefault,
+ flag: false
+ })
+ assert.deepEqual(calls[3], {
+ type: 'keydown',
+ dispatch: wrapper.instance().handleScrollAndEscKeys,
+ flag: false
+ })
+ window.addEventListener = addEventListenerBak
+ })
+
+ it('.enableScroll() should restore event listeners', () => {
+ const wrapper = mount(
)
+ const addEventListenerBak = window.addEventListener
+ const removeEventListenerBak = window.removeEventListener
+ const calls = []
+ window.addEventListener = () => {}
+ window.removeEventListener = (type, dispatch, flag) => {
+ calls.push({
+ type,
+ dispatch,
+ flag
+ })
+ }
+ wrapper.instance().disableScroll()
+ wrapper.instance().enableScroll()
+ assert.deepEqual(calls[0], {
+ type: 'DOMMouseScroll',
+ dispatch: preventDefault,
+ flag: false
+ })
+ assert.deepEqual(calls[1], {
+ type: 'wheel',
+ dispatch: preventDefault,
+ flag: false
+ })
+ assert.deepEqual(calls[2], {
+ type: 'touchmove',
+ dispatch: preventDefault,
+ flag: false
+ })
+ assert.deepEqual(calls[3], {
+ type: 'keydown',
+ dispatch: wrapper.instance().handleScrollAndEscKeys,
+ flag: false
+ })
+ window.addEventListener = addEventListenerBak
+ window.removeEventListener = removeEventListenerBak
+ })
+
+ it('helper preventDefault should preventDefault and set returnValue=false', () => {
+ let wasCalled
+ const event = {
+ preventDefault: () => {
+ wasCalled = true
+ }
+ }
+ preventDefault(event)
+ assert.equal(event.returnValue, false)
+ assert(wasCalled)
+ })
+
+ it('should disable scroll and blur activeElement when getting visible', () => {
+ const wrapper = mount(
)
+ let disableWasCalled
+ wrapper.instance().disableScroll = () => {
+ disableWasCalled = true
+ }
+ let blurWasCalled
+ document.activeElement.blur = () => {
+ blurWasCalled = true
+ }
+ wrapper.setProps({visible: true})
+ assert(disableWasCalled)
+ assert(blurWasCalled)
+ })
+
+ it('should enable scroll when getting invisible', () => {
+ const wrapper = mount(
)
+ let enableWasCalled
+ wrapper.instance().enableScroll = () => {
+ enableWasCalled = true
+ }
+ wrapper.setProps({visible: false})
+ assert(enableWasCalled)
+ })
+
+ it('click on modal should not propagate', () => {
+ const wrapper = mount(
)
+ let wasCalled
+ wrapper.find('.mdc-Modal').simulate('click', {
+ stopPropagation: () => {
+ wasCalled = true
+ }
+ })
+ assert(wasCalled)
+ })
+
+ it('touchend on modal should not propagate', () => {
+ const wrapper = mount(
)
+ let wasCalled
+ wrapper.find('.mdc-Modal').simulate('touchend', {
+ stopPropagation: () => {
+ wasCalled = true
+ }
+ })
+ assert(wasCalled)
+ })
+
+ it('handleScrollAndEscKeys should prevent default for scroll keys', () => {
+ const wrapper = mount(
)
+ let wasCalled
+ let result = wrapper.instance().handleScrollAndEscKeys({
+ keyCode: 32,
+ preventDefault: () => {
+ wasCalled = true
+ }
+ })
+ assert(wasCalled)
+ assert.equal(result, false)
+ })
+
+ it('handleScrollAndEscKeys should prevent default for scroll keys', () => {
+ let toggleArg
+ const wrapper = mount(
{
+ toggleArg = arg
+ }} />)
+ wrapper.instance().handleScrollAndEscKeys({
+ keyCode: 27
+ })
+ assert.equal(toggleArg, false)
+ })
})