From aa388a692e5a331afec671f8e0339c7742bb0ebf Mon Sep 17 00:00:00 2001 From: Yev Vlasenko Date: Sun, 26 Nov 2017 11:30:19 +0000 Subject: [PATCH] Fixed focusing issue --- demo/client_side_rendering/src/App.vue | 10 +- dist/index.js | 40 ++-- dist/ssr.index.js | 40 ++-- package.json | 2 +- src/Dialog.vue | 305 ++++++++++++------------- src/Modal.vue | 21 +- 6 files changed, 218 insertions(+), 200 deletions(-) diff --git a/demo/client_side_rendering/src/App.vue b/demo/client_side_rendering/src/App.vue index a4e983a..5772188 100644 --- a/demo/client_side_rendering/src/App.vue +++ b/demo/client_side_rendering/src/App.vue @@ -8,7 +8,10 @@ + @before-opened="dialogEvent('before-open')" + @before-closed="dialogEvent('before-close')" + @opened="dialogEvent('opened')" + @closed="dialogEvent('closed')"/> { alert('LIKE LIKE LIKE') } @@ -199,8 +203,8 @@ export default { }) }, - onEveryDialogOpen () { - console.log('Opened dialog') + dialogEvent (eventName) { + console.log('Dialog event: ' + eventName) } }, } diff --git a/dist/index.js b/dist/index.js index c15f52e..88b7e3b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -207,7 +207,7 @@ }, function(module, exports, __webpack_require__) { __webpack_require__(18); var Component = __webpack_require__(1)(__webpack_require__(7), __webpack_require__(15), null, null); - Component.options.__file = "/Users/admin/Projects/vue/vue-js-modal/src/Dialog.vue", + Component.options.__file = "/Users/yev.vlasenko2/Projects/vue/vue-js-modal/src/Dialog.vue", Component.esModule && Object.keys(Component.esModule).some(function(key) { return "default" !== key && "__esModule" !== key; }) && console.error("named exports are not supported in *.vue files."), Component.options.functional && console.error("[vue-loader] Dialog.vue: functional components are not supported with templates, they should use render functions."), @@ -215,7 +215,7 @@ }, function(module, exports, __webpack_require__) { __webpack_require__(19); var Component = __webpack_require__(1)(__webpack_require__(8), __webpack_require__(16), null, null); - Component.options.__file = "/Users/admin/Projects/vue/vue-js-modal/src/Modal.vue", + Component.options.__file = "/Users/yev.vlasenko2/Projects/vue/vue-js-modal/src/Modal.vue", Component.esModule && Object.keys(Component.esModule).some(function(key) { return "default" !== key && "__esModule" !== key; }) && console.error("named exports are not supported in *.vue files."), Component.options.functional && console.error("[vue-loader] Modal.vue: functional components are not supported with templates, they should use render functions."), @@ -260,15 +260,25 @@ }, methods: { beforeOpened: function(event) { - this.params = event.params || {}, this.$emit("before-opened", event); + window.addEventListener("keyup", this.onKeyUp), this.params = event.params || {}, + this.$emit("before-opened", event); }, beforeClosed: function(event) { - this.params = {}, this.$emit("before-closed", event); + window.removeEventListener("keyup", this.onKeyUp), this.params = {}, this.$emit("before-closed", event); }, click: function(i, event) { - var button = this.buttons[i]; - if ("function" == typeof button.handler) return button.handler(i, event); - this.$modal.hide("dialog"); + var source = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "click", button = this.buttons[i]; + button && "function" == typeof button.handler ? button.handler(i, event, { + source: source + }) : this.$modal.hide("dialog"); + }, + onKeyUp: function(event) { + if (13 === event.which && this.buttons.length > 0) { + var buttonIndex = 1 === this.buttons.length ? 0 : this.buttons.findIndex(function(button) { + return button.default; + }); + -1 !== buttonIndex && this.click(buttonIndex, event, "keypress"); + } } } }; @@ -490,7 +500,7 @@ modal.heightType = height.type; }, onEscapeKeyUp: function(event) { - 27 === (event.keyCode || event.which) && this.visible && this.$modal.hide(this.name); + 27 === event.which && this.visible && this.$modal.hide(this.name); }, onWindowResize: function() { this.window.width = window.innerWidth, this.window.height = window.innerHeight; @@ -514,8 +524,8 @@ }, toggle: function(state, params) { var reset = this.reset, scrollable = this.scrollable, visible = this.visible, beforeEventName = visible ? "before-close" : "before-open"; - "before-open" === beforeEventName ? (reset && (this.setInitialSize(), this.shift.left = 0, - this.shift.top = 0), scrollable && document.body.classList.add("v--modal-block-scroll")) : scrollable && document.body.classList.remove("v--modal-block-scroll"); + "before-open" === beforeEventName ? (document.activeElement && document.activeElement.blur(), + reset && (this.setInitialSize(), this.shift.left = 0, this.shift.top = 0), scrollable && document.body.classList.add("v--modal-block-scroll")) : scrollable && document.body.classList.remove("v--modal-block-scroll"); var stopEventExecution = !1, stop = function() { stopEventExecution = !0; }, beforeEvent = this.genEventObject({ @@ -566,10 +576,10 @@ removeDraggableListeners: function() {}, callAfterEvent: function(state) { state ? this.connectObserver() : this.disconnectObserver(); - var afterEventName = state ? "opened" : "closed", afterEvent = this.genEventObject({ + var eventName = state ? "opened" : "closed", event = this.genEventObject({ state: state }); - this.$emit(afterEventName, afterEvent); + this.$emit(eventName, event); }, updateRenderedHeight: function() { this.$refs.modal && (this.modal.renderedHeight = this.$refs.modal.getBoundingClientRect().height); @@ -706,7 +716,7 @@ }; exports.default = parse; }, function(module, exports, __webpack_require__) { - exports = module.exports = __webpack_require__(0)(), exports.push([ module.i, "\n.vue-dialog div {\n box-sizing: border-box;\n}\n.vue-dialog .dialog-flex {\n width: 100%;\n height: 100%;\n}\n.vue-dialog .dialog-content {\n flex: 1 0 auto;\n width: 100%;\n padding: 15px;\n font-size: 14px;\n}\n.vue-dialog .dialog-c-title {\n font-weight: 600;\n padding-bottom: 15px;\n}\n.vue-dialog .dialog-c-text {\n}\n.vue-dialog .vue-dialog-buttons {\n display: flex;\n flex: 0 1 auto;\n width: 100%;\n border-top: 1px solid #eee;\n}\n.vue-dialog .vue-dialog-buttons-none {\n width: 100%;\n padding-bottom: 15px;\n}\n.vue-dialog-button {\n font-size: 12px !important;\n background: transparent;\n padding: 0;\n margin: 0;\n border: 0;\n cursor: pointer;\n box-sizing: border-box;\n line-height: 40px;\n height: 40px;\n color:inherit;\n font:inherit;\n outline: none;\n}\n.vue-dialog-button:hover {\n background: rgba(0, 0, 0, 0.01);\n}\n.vue-dialog-button:active {\n background: rgba(0, 0, 0, 0.025);\n}\n.vue-dialog-button:not(:first-of-type) {\n border-left: 1px solid #eee;\n}\n", "" ]); + exports = module.exports = __webpack_require__(0)(), exports.push([ module.i, "\n.vue-dialog div {\n box-sizing: border-box;\n}\n.vue-dialog .dialog-flex {\n width: 100%;\n height: 100%;\n}\n.vue-dialog .dialog-content {\n flex: 1 0 auto;\n width: 100%;\n padding: 15px;\n font-size: 14px;\n}\n.vue-dialog .dialog-c-title {\n font-weight: 600;\n padding-bottom: 15px;\n}\n.vue-dialog .dialog-c-text {\n}\n.vue-dialog .vue-dialog-buttons {\n display: flex;\n flex: 0 1 auto;\n width: 100%;\n border-top: 1px solid #eee;\n}\n.vue-dialog .vue-dialog-buttons-none {\n width: 100%;\n padding-bottom: 15px;\n}\n.vue-dialog-button {\n font-size: 12px !important;\n background: transparent;\n padding: 0;\n margin: 0;\n border: 0;\n cursor: pointer;\n box-sizing: border-box;\n line-height: 40px;\n height: 40px;\n color: inherit;\n font: inherit;\n outline: none;\n}\n.vue-dialog-button:hover {\n background: rgba(0, 0, 0, 0.01);\n}\n.vue-dialog-button:active {\n background: rgba(0, 0, 0, 0.025);\n}\n.vue-dialog-button:not(:first-of-type) {\n border-left: 1px solid #eee;\n}\n", "" ]); }, function(module, exports, __webpack_require__) { exports = module.exports = __webpack_require__(0)(), exports.push([ module.i, "\n.v--modal-block-scroll {\n overflow: hidden;\n position: fixed;\n width: 100vw;\n}\n.v--modal-overlay {\n position: fixed;\n box-sizing: border-box;\n left: 0;\n top: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(0, 0, 0, 0.2);\n z-index: 999;\n opacity: 1;\n}\n.v--modal-overlay.scrollable {\n height: 100%;\n min-height: 100vh;\n overflow-y: auto;\n padding-bottom: 10px;\n -webkit-overflow-scrolling: touch;\n}\n.v--modal-overlay .v--modal-box {\n position: relative;\n overflow: hidden;\n box-sizing: border-box;\n}\n.v--modal-overlay.scrollable .v--modal-box {\n margin-bottom: 2px;\n /* transition: top 0.2s ease; */\n}\n.v--modal {\n background-color: white;\n text-align: left;\n border-radius: 3px;\n box-shadow: 0 20px 60px -2px rgba(27, 33, 58, .4);\n padding: 0;\n}\n.v--modal.v--modal-fullscreen {\n width: 100vw;\n height: 100vh;\n margin: 0;\n left: 0;\n top: 0;\n}\n.v--modal-top-right {\n display: block;\n position: absolute;\n right: 0;\n top: 0;\n}\n.overlay-fade-enter-active, .overlay-fade-leave-active {\n transition: all 0.2s;\n}\n.overlay-fade-enter, .overlay-fade-leave-active {\n opacity: 0;\n}\n.nice-modal-fade-enter-active, .nice-modal-fade-leave-active {\n transition: all 0.4s;\n}\n.nice-modal-fade-enter, .nice-modal-fade-leave-active {\n opacity: 0;\n transform: translateY(-20px);\n}\n", "" ]); }, function(module, exports, __webpack_require__) { @@ -714,7 +724,7 @@ }, function(module, exports, __webpack_require__) { __webpack_require__(20); var Component = __webpack_require__(1)(__webpack_require__(9), __webpack_require__(17), null, null); - Component.options.__file = "/Users/admin/Projects/vue/vue-js-modal/src/Resizer.vue", + Component.options.__file = "/Users/yev.vlasenko2/Projects/vue/vue-js-modal/src/Resizer.vue", Component.esModule && Object.keys(Component.esModule).some(function(key) { return "default" !== key && "__esModule" !== key; }) && console.error("named exports are not supported in *.vue files."), Component.options.functional && console.error("[vue-loader] Resizer.vue: functional components are not supported with templates, they should use render functions."), @@ -771,7 +781,7 @@ $event.stopPropagation(), _vm.click(i, $event); } } - }, [ _vm._v("\n " + _vm._s(button.title) + "\n ") ]); + }, [ _vm._v("\n " + _vm._s(button.title) + "\n ") ]); })) : _c("div", { staticClass: "vue-dialog-buttons-none" }) ]); diff --git a/dist/ssr.index.js b/dist/ssr.index.js index e0e2170..dc0a400 100644 --- a/dist/ssr.index.js +++ b/dist/ssr.index.js @@ -161,7 +161,7 @@ }, function(module, exports, __webpack_require__) { __webpack_require__(18); var Component = __webpack_require__(1)(__webpack_require__(7), __webpack_require__(15), null, null); - Component.options.__file = "/Users/admin/Projects/vue/vue-js-modal/src/Dialog.vue", + Component.options.__file = "/Users/yev.vlasenko2/Projects/vue/vue-js-modal/src/Dialog.vue", Component.esModule && Object.keys(Component.esModule).some(function(key) { return "default" !== key && "__esModule" !== key; }) && console.error("named exports are not supported in *.vue files."), Component.options.functional && console.error("[vue-loader] Dialog.vue: functional components are not supported with templates, they should use render functions."), @@ -169,7 +169,7 @@ }, function(module, exports, __webpack_require__) { __webpack_require__(19); var Component = __webpack_require__(1)(__webpack_require__(8), __webpack_require__(16), null, null); - Component.options.__file = "/Users/admin/Projects/vue/vue-js-modal/src/Modal.vue", + Component.options.__file = "/Users/yev.vlasenko2/Projects/vue/vue-js-modal/src/Modal.vue", Component.esModule && Object.keys(Component.esModule).some(function(key) { return "default" !== key && "__esModule" !== key; }) && console.error("named exports are not supported in *.vue files."), Component.options.functional && console.error("[vue-loader] Modal.vue: functional components are not supported with templates, they should use render functions."), @@ -214,15 +214,25 @@ }, methods: { beforeOpened: function(event) { - this.params = event.params || {}, this.$emit("before-opened", event); + window.addEventListener("keyup", this.onKeyUp), this.params = event.params || {}, + this.$emit("before-opened", event); }, beforeClosed: function(event) { - this.params = {}, this.$emit("before-closed", event); + window.removeEventListener("keyup", this.onKeyUp), this.params = {}, this.$emit("before-closed", event); }, click: function(i, event) { - var button = this.buttons[i]; - if ("function" == typeof button.handler) return button.handler(i, event); - this.$modal.hide("dialog"); + var source = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "click", button = this.buttons[i]; + button && "function" == typeof button.handler ? button.handler(i, event, { + source: source + }) : this.$modal.hide("dialog"); + }, + onKeyUp: function(event) { + if (13 === event.which && this.buttons.length > 0) { + var buttonIndex = 1 === this.buttons.length ? 0 : this.buttons.findIndex(function(button) { + return button.default; + }); + -1 !== buttonIndex && this.click(buttonIndex, event, "keypress"); + } } } }; @@ -444,7 +454,7 @@ modal.heightType = height.type; }, onEscapeKeyUp: function(event) { - 27 === (event.keyCode || event.which) && this.visible && this.$modal.hide(this.name); + 27 === event.which && this.visible && this.$modal.hide(this.name); }, onWindowResize: function() { this.window.width = window.innerWidth, this.window.height = window.innerHeight; @@ -468,8 +478,8 @@ }, toggle: function(state, params) { var reset = this.reset, scrollable = this.scrollable, visible = this.visible, beforeEventName = visible ? "before-close" : "before-open"; - "before-open" === beforeEventName ? (reset && (this.setInitialSize(), this.shift.left = 0, - this.shift.top = 0), scrollable && document.body.classList.add("v--modal-block-scroll")) : scrollable && document.body.classList.remove("v--modal-block-scroll"); + "before-open" === beforeEventName ? (document.activeElement && document.activeElement.blur(), + reset && (this.setInitialSize(), this.shift.left = 0, this.shift.top = 0), scrollable && document.body.classList.add("v--modal-block-scroll")) : scrollable && document.body.classList.remove("v--modal-block-scroll"); var stopEventExecution = !1, stop = function() { stopEventExecution = !0; }, beforeEvent = this.genEventObject({ @@ -520,10 +530,10 @@ removeDraggableListeners: function() {}, callAfterEvent: function(state) { state ? this.connectObserver() : this.disconnectObserver(); - var afterEventName = state ? "opened" : "closed", afterEvent = this.genEventObject({ + var eventName = state ? "opened" : "closed", event = this.genEventObject({ state: state }); - this.$emit(afterEventName, afterEvent); + this.$emit(eventName, event); }, updateRenderedHeight: function() { this.$refs.modal && (this.modal.renderedHeight = this.$refs.modal.getBoundingClientRect().height); @@ -660,7 +670,7 @@ }; exports.default = parse; }, function(module, exports, __webpack_require__) { - exports = module.exports = __webpack_require__(0)(), exports.push([ module.i, "\n.vue-dialog div {\n box-sizing: border-box;\n}\n.vue-dialog .dialog-flex {\n width: 100%;\n height: 100%;\n}\n.vue-dialog .dialog-content {\n flex: 1 0 auto;\n width: 100%;\n padding: 15px;\n font-size: 14px;\n}\n.vue-dialog .dialog-c-title {\n font-weight: 600;\n padding-bottom: 15px;\n}\n.vue-dialog .dialog-c-text {\n}\n.vue-dialog .vue-dialog-buttons {\n display: flex;\n flex: 0 1 auto;\n width: 100%;\n border-top: 1px solid #eee;\n}\n.vue-dialog .vue-dialog-buttons-none {\n width: 100%;\n padding-bottom: 15px;\n}\n.vue-dialog-button {\n font-size: 12px !important;\n background: transparent;\n padding: 0;\n margin: 0;\n border: 0;\n cursor: pointer;\n box-sizing: border-box;\n line-height: 40px;\n height: 40px;\n color:inherit;\n font:inherit;\n outline: none;\n}\n.vue-dialog-button:hover {\n background: rgba(0, 0, 0, 0.01);\n}\n.vue-dialog-button:active {\n background: rgba(0, 0, 0, 0.025);\n}\n.vue-dialog-button:not(:first-of-type) {\n border-left: 1px solid #eee;\n}\n", "" ]); + exports = module.exports = __webpack_require__(0)(), exports.push([ module.i, "\n.vue-dialog div {\n box-sizing: border-box;\n}\n.vue-dialog .dialog-flex {\n width: 100%;\n height: 100%;\n}\n.vue-dialog .dialog-content {\n flex: 1 0 auto;\n width: 100%;\n padding: 15px;\n font-size: 14px;\n}\n.vue-dialog .dialog-c-title {\n font-weight: 600;\n padding-bottom: 15px;\n}\n.vue-dialog .dialog-c-text {\n}\n.vue-dialog .vue-dialog-buttons {\n display: flex;\n flex: 0 1 auto;\n width: 100%;\n border-top: 1px solid #eee;\n}\n.vue-dialog .vue-dialog-buttons-none {\n width: 100%;\n padding-bottom: 15px;\n}\n.vue-dialog-button {\n font-size: 12px !important;\n background: transparent;\n padding: 0;\n margin: 0;\n border: 0;\n cursor: pointer;\n box-sizing: border-box;\n line-height: 40px;\n height: 40px;\n color: inherit;\n font: inherit;\n outline: none;\n}\n.vue-dialog-button:hover {\n background: rgba(0, 0, 0, 0.01);\n}\n.vue-dialog-button:active {\n background: rgba(0, 0, 0, 0.025);\n}\n.vue-dialog-button:not(:first-of-type) {\n border-left: 1px solid #eee;\n}\n", "" ]); }, function(module, exports, __webpack_require__) { exports = module.exports = __webpack_require__(0)(), exports.push([ module.i, "\n.v--modal-block-scroll {\n overflow: hidden;\n position: fixed;\n width: 100vw;\n}\n.v--modal-overlay {\n position: fixed;\n box-sizing: border-box;\n left: 0;\n top: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(0, 0, 0, 0.2);\n z-index: 999;\n opacity: 1;\n}\n.v--modal-overlay.scrollable {\n height: 100%;\n min-height: 100vh;\n overflow-y: auto;\n padding-bottom: 10px;\n -webkit-overflow-scrolling: touch;\n}\n.v--modal-overlay .v--modal-box {\n position: relative;\n overflow: hidden;\n box-sizing: border-box;\n}\n.v--modal-overlay.scrollable .v--modal-box {\n margin-bottom: 2px;\n /* transition: top 0.2s ease; */\n}\n.v--modal {\n background-color: white;\n text-align: left;\n border-radius: 3px;\n box-shadow: 0 20px 60px -2px rgba(27, 33, 58, .4);\n padding: 0;\n}\n.v--modal.v--modal-fullscreen {\n width: 100vw;\n height: 100vh;\n margin: 0;\n left: 0;\n top: 0;\n}\n.v--modal-top-right {\n display: block;\n position: absolute;\n right: 0;\n top: 0;\n}\n.overlay-fade-enter-active, .overlay-fade-leave-active {\n transition: all 0.2s;\n}\n.overlay-fade-enter, .overlay-fade-leave-active {\n opacity: 0;\n}\n.nice-modal-fade-enter-active, .nice-modal-fade-leave-active {\n transition: all 0.4s;\n}\n.nice-modal-fade-enter, .nice-modal-fade-leave-active {\n opacity: 0;\n transform: translateY(-20px);\n}\n", "" ]); }, function(module, exports, __webpack_require__) { @@ -668,7 +678,7 @@ }, function(module, exports, __webpack_require__) { __webpack_require__(20); var Component = __webpack_require__(1)(__webpack_require__(9), __webpack_require__(17), null, null); - Component.options.__file = "/Users/admin/Projects/vue/vue-js-modal/src/Resizer.vue", + Component.options.__file = "/Users/yev.vlasenko2/Projects/vue/vue-js-modal/src/Resizer.vue", Component.esModule && Object.keys(Component.esModule).some(function(key) { return "default" !== key && "__esModule" !== key; }) && console.error("named exports are not supported in *.vue files."), Component.options.functional && console.error("[vue-loader] Resizer.vue: functional components are not supported with templates, they should use render functions."), @@ -725,7 +735,7 @@ $event.stopPropagation(), _vm.click(i, $event); } } - }, [ _vm._v("\n " + _vm._s(button.title) + "\n ") ]); + }, [ _vm._v("\n " + _vm._s(button.title) + "\n ") ]); })) : _c("div", { staticClass: "vue-dialog-buttons-none" }) ]); diff --git a/package.json b/package.json index 262676f..11a198b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vue-js-modal", "description": "Modal Component for Vue.js", - "version": "1.3.5", + "version": "1.3.6", "author": "euvl ", "main": "dist/index.js", "repository": { diff --git a/src/Dialog.vue b/src/Dialog.vue index 2c7877d..19df0c0 100644 --- a/src/Dialog.vue +++ b/src/Dialog.vue @@ -1,179 +1,176 @@ diff --git a/src/Modal.vue b/src/Modal.vue index 844429d..6115c6c 100644 --- a/src/Modal.vue +++ b/src/Modal.vue @@ -258,7 +258,7 @@ } if (this.clickToClose) { - // window.addEventListener('keyup', this.onEscapeKeyUp) + window.addEventListener('keyup', this.onEscapeKeyUp) } }, /** @@ -268,7 +268,7 @@ window.removeEventListener('resize', this.onWindowResize) if (this.clickToClose) { - // window.removeEventListener('keyup', this.onEscapeKeyUp) + window.removeEventListener('keyup', this.onEscapeKeyUp) } }, computed: { @@ -381,9 +381,9 @@ }, onEscapeKeyUp (event) { - // if (event.which === 27 && this.visible) { - // this.$modal.hide(this.name) - // } + if (event.which === 27 && this.visible) { + this.$modal.hide(this.name) + } }, onWindowResize () { @@ -427,8 +427,6 @@ toggle (state, params) { const { reset, scrollable, visible } = this - console.log('woot') - const beforeEventName = visible ? 'before-close' : 'before-open' @@ -441,6 +439,7 @@ if (document.activeElement) { document.activeElement.blur() } + if (reset) { this.setInitialSize() @@ -577,12 +576,10 @@ this.disconnectObserver() } - const afterEventName = state - ? 'opened' - : 'closed' - const afterEvent = this.genEventObject({ state }) + const eventName = state ? 'opened' : 'closed' + const event = this.genEventObject({ state }) - this.$emit(afterEventName, afterEvent) + this.$emit(eventName, event) }, /**