From 95cd98b47faf20f62e26b144d8df284c62f37f0c Mon Sep 17 00:00:00 2001 From: Nathan James Date: Fri, 30 Jun 2023 14:46:55 +0100 Subject: [PATCH 1/4] Esc event listener only when open --- src/components/VueModal.vue | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/components/VueModal.vue b/src/components/VueModal.vue index a214c10..d2ad70a 100644 --- a/src/components/VueModal.vue +++ b/src/components/VueModal.vue @@ -91,6 +91,10 @@ export default { type: String, default: "75%", }, + escClosesModal: { + type: Boolean, + default: true, + }, }, data() { return { @@ -100,11 +104,6 @@ export default { }, created() { //listen for esc key press - window.addEventListener('keydown', (event) => { - if (event.key === 'Escape' || event.key === 'Esc' || event.key === 27) { - this.handleOutsideClick(); - } - }); }, watch: { show(newValue) { @@ -180,6 +179,7 @@ export default { }, closeModal() { this.show = false; + window.removeEventListener('keydown', this.handleEsc); }, handleOutsideClick() { if (this.closeOnOutsideClick) { @@ -193,9 +193,18 @@ export default { } }, openModal() { + window.addEventListener('keydown', this.handleEsc); this.initiated = true; this.show = true; }, + handleEsc(event) { + if ( + (event.key === 'Escape' || event.key === 'Esc' || event.key === 27) + && this.escClosesModal + ) { + this.handleOutsideClick(); + } + } }, }; From 5841dad0b67142ed716a3a60bbcf65316b259483 Mon Sep 17 00:00:00 2001 From: Nathan James Date: Fri, 30 Jun 2023 14:48:17 +0100 Subject: [PATCH 2/4] Version bump & build --- dist/style.css | 2 +- dist/vue-modal.js | 58 ++++++++++++++++++++++-------------------- dist/vue-modal.umd.cjs | 2 +- package.json | 2 +- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/dist/style.css b/dist/style.css index cf8f835..38c3d5d 100644 --- a/dist/style.css +++ b/dist/style.css @@ -1 +1 @@ -.modal-backdrop[data-v-3a19ad3a]{content:"";position:absolute;position:fixed;top:0;right:0;bottom:0;left:0;z-index:998;background:#2c3e50;opacity:.6;cursor:pointer}.modal[data-v-3a19ad3a]{position:fixed;display:block;top:0;right:0;bottom:0;left:0;margin:auto;width:700px;border-radius:8px;box-shadow:0 -2px 5px #00000026;background:#FFF;z-index:999;transform:none;max-width:95%;max-height:75%;text-align:left;overflow:auto;height:fit-content;-ms-overflow-style:none;scrollbar-width:none}.modal .model-content[data-v-3a19ad3a]{margin:2em}.modal .model-content[data-v-3a19ad3a] ::-webkit-scrollbar{display:none}.modal[data-v-3a19ad3a]::-webkit-scrollbar{display:none}.modal header.--sticky[data-v-3a19ad3a]{position:sticky;background-color:inherit;z-index:1055;margin:0}.modal header[data-v-3a19ad3a],.modal footer[data-v-3a19ad3a]{margin:2em}.modal footer.--sticky[data-v-3a19ad3a]{position:sticky;background-color:inherit;z-index:1055;margin:0;bottom:0;width:100%}.modal footer.--sticky .buttons-footer[data-v-3a19ad3a]{padding:2em}.modal footer .buttons-footer[data-v-3a19ad3a]{display:flex;justify-content:flex-end}.bounce-enter-active[data-v-3a19ad3a]{animation:bounce-in-3a19ad3a .3s}.bounce-leave-active[data-v-3a19ad3a]{animation:bounce-in-3a19ad3a .3s reverse}.zoom-enter-active[data-v-3a19ad3a]{animation:zoom-in-3a19ad3a .3s}.zoom-leave-active[data-v-3a19ad3a]{animation:zoom-in-3a19ad3a .3s reverse}@keyframes bounce-in-3a19ad3a{0%{transform:scale(0)}50%{transform:scale(1.25)}to{transform:scale(1)}}@keyframes zoom-in-3a19ad3a{0%{transform:scale(0)}to{transform:scale(1)}}.fade-enter-active[data-v-3a19ad3a],.fade-leave-active[data-v-3a19ad3a]{transition:opacity .3s ease}.fade-enter-from[data-v-3a19ad3a],.fade-leave-to[data-v-3a19ad3a]{opacity:0}.btn[data-v-3a19ad3a]{border:1px solid rgb(209,213,219);border-radius:.5rem;box-sizing:border-box;color:#111827;font-family:Inter var,ui-sans-serif,system-ui,-apple-system,system-ui,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-size:.875rem;font-weight:600;line-height:1.25rem;padding:.75rem 1rem;text-align:center;text-decoration:none #D1D5DB solid;text-decoration-thickness:auto;box-shadow:0 1px 2px #0000000d;cursor:pointer;user-select:none;-webkit-user-select:none;touch-action:manipulation;transition:all .2s ease-in-out}.btn.btn-primary[data-v-3a19ad3a]{background-color:#00a8ff;color:#fff;opacity:.8}.btn.btn-primary[data-v-3a19ad3a]:hover{opacity:1}.btn.btn-danger[data-v-3a19ad3a]{background-color:red;color:#fff;opacity:.8}.btn.btn-danger[data-v-3a19ad3a]:hover{opacity:1}.btn.btn-large[data-v-3a19ad3a]{padding:10px 24px;line-height:1.5}.d-flex[data-v-3a19ad3a]{display:flex}.d-flex.justify-content-end[data-v-3a19ad3a]{justify-content:flex-end}.mt-4[data-v-3a19ad3a]{margin-top:4rem} +.modal-backdrop[data-v-8c6374f0]{content:"";position:absolute;position:fixed;top:0;right:0;bottom:0;left:0;z-index:998;background:#2c3e50;opacity:.6;cursor:pointer}.modal[data-v-8c6374f0]{position:fixed;display:block;top:0;right:0;bottom:0;left:0;margin:auto;width:700px;border-radius:8px;box-shadow:0 -2px 5px #00000026;background:#FFF;z-index:999;transform:none;max-width:95%;max-height:75%;text-align:left;overflow:auto;height:fit-content;-ms-overflow-style:none;scrollbar-width:none}.modal .model-content[data-v-8c6374f0]{margin:2em}.modal .model-content[data-v-8c6374f0] ::-webkit-scrollbar{display:none}.modal[data-v-8c6374f0]::-webkit-scrollbar{display:none}.modal header.--sticky[data-v-8c6374f0]{position:sticky;background-color:inherit;z-index:1055;margin:0}.modal header[data-v-8c6374f0],.modal footer[data-v-8c6374f0]{margin:2em}.modal footer.--sticky[data-v-8c6374f0]{position:sticky;background-color:inherit;z-index:1055;margin:0;bottom:0;width:100%}.modal footer.--sticky .buttons-footer[data-v-8c6374f0]{padding:2em}.modal footer .buttons-footer[data-v-8c6374f0]{display:flex;justify-content:flex-end}.bounce-enter-active[data-v-8c6374f0]{animation:bounce-in-8c6374f0 .3s}.bounce-leave-active[data-v-8c6374f0]{animation:bounce-in-8c6374f0 .3s reverse}.zoom-enter-active[data-v-8c6374f0]{animation:zoom-in-8c6374f0 .3s}.zoom-leave-active[data-v-8c6374f0]{animation:zoom-in-8c6374f0 .3s reverse}@keyframes bounce-in-8c6374f0{0%{transform:scale(0)}50%{transform:scale(1.25)}to{transform:scale(1)}}@keyframes zoom-in-8c6374f0{0%{transform:scale(0)}to{transform:scale(1)}}.fade-enter-active[data-v-8c6374f0],.fade-leave-active[data-v-8c6374f0]{transition:opacity .3s ease}.fade-enter-from[data-v-8c6374f0],.fade-leave-to[data-v-8c6374f0]{opacity:0}.btn[data-v-8c6374f0]{border:1px solid rgb(209,213,219);border-radius:.5rem;box-sizing:border-box;color:#111827;font-family:Inter var,ui-sans-serif,system-ui,-apple-system,system-ui,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-size:.875rem;font-weight:600;line-height:1.25rem;padding:.75rem 1rem;text-align:center;text-decoration:none #D1D5DB solid;text-decoration-thickness:auto;box-shadow:0 1px 2px #0000000d;cursor:pointer;user-select:none;-webkit-user-select:none;touch-action:manipulation;transition:all .2s ease-in-out}.btn.btn-primary[data-v-8c6374f0]{background-color:#00a8ff;color:#fff;opacity:.8}.btn.btn-primary[data-v-8c6374f0]:hover{opacity:1}.btn.btn-danger[data-v-8c6374f0]{background-color:red;color:#fff;opacity:.8}.btn.btn-danger[data-v-8c6374f0]:hover{opacity:1}.btn.btn-large[data-v-8c6374f0]{padding:10px 24px;line-height:1.5}.d-flex[data-v-8c6374f0]{display:flex}.d-flex.justify-content-end[data-v-8c6374f0]{justify-content:flex-end}.mt-4[data-v-8c6374f0]{margin-top:4rem} diff --git a/dist/vue-modal.js b/dist/vue-modal.js index eb1025f..aa12e32 100644 --- a/dist/vue-modal.js +++ b/dist/vue-modal.js @@ -1,10 +1,10 @@ -import { openBlock as l, createElementBlock as d, createVNode as m, Transition as f, withCtx as k, createCommentVNode as u, withDirectives as C, normalizeStyle as p, createElementVNode as o, normalizeClass as r, renderSlot as c, toDisplayString as y, vShow as g } from "vue"; +import { openBlock as l, createElementBlock as d, createVNode as m, Transition as f, withCtx as y, createCommentVNode as u, withDirectives as C, normalizeStyle as p, createElementVNode as s, normalizeClass as r, renderSlot as c, toDisplayString as k, vShow as g } from "vue"; const B = (t, e) => { const n = t.__vccOpts || t; - for (const [h, s] of e) - n[h] = s; + for (const [h, o] of e) + n[h] = o; return n; -}, b = { +}, w = { name: "VueModal", props: { confirmButtonText: { @@ -58,6 +58,10 @@ const B = (t, e) => { maxHeight: { type: String, default: "75%" + }, + escClosesModal: { + type: Boolean, + default: !0 } }, data() { @@ -67,9 +71,6 @@ const B = (t, e) => { }; }, created() { - window.addEventListener("keydown", (t) => { - (t.key === "Escape" || t.key === "Esc" || t.key === 27) && this.handleOutsideClick(); - }); }, watch: { show(t) { @@ -128,7 +129,7 @@ const B = (t, e) => { this.$emit("cancel"), this.closeOnButtonClick && this.closeModal(); }, closeModal() { - this.show = !1; + this.show = !1, window.removeEventListener("keydown", this.handleEsc); }, handleOutsideClick() { this.closeOnOutsideClick && this.cancelButtonClicked(); @@ -137,15 +138,18 @@ const B = (t, e) => { this.$emit("confirm"), this.closeOnButtonClick && this.closeModal(); }, openModal() { - this.initiated = !0, this.show = !0; + window.addEventListener("keydown", this.handleEsc), this.initiated = !0, this.show = !0; + }, + handleEsc(t) { + (t.key === "Escape" || t.key === "Esc" || t.key === 27) && this.escClosesModal && this.handleOutsideClick(); } } -}, w = { class: "model-content" }, x = { class: "d-block" }, _ = { class: "buttons-footer" }; -function v(t, e, n, h, s, i) { +}, b = { class: "model-content" }, x = { class: "d-block" }, _ = { class: "buttons-footer" }; +function v(t, e, n, h, o, i) { return l(), d("div", null, [ m(f, { name: i.backdropTransition }, { - default: k(() => [ - s.show ? (l(), d("div", { + default: y(() => [ + o.show ? (l(), d("div", { key: 0, class: "modal-backdrop", onClick: e[0] || (e[0] = (...a) => i.handleOutsideClick && i.handleOutsideClick(...a)) @@ -154,53 +158,53 @@ function v(t, e, n, h, s, i) { _: 1 }, 8, ["name"]), m(f, { name: i.modalTransition }, { - default: k(() => [ - s.initiated ? C((l(), d("div", { + default: y(() => [ + o.initiated ? C((l(), d("div", { key: 0, class: "modal", style: p({ width: i.computedWidth, "max-height": i.computedMaxHeight }) }, [ - o("header", { + s("header", { class: r(i.headerClass) }, [ c(t.$slots, "header", {}, void 0, !0) ], 2), - o("div", w, [ - o("section", null, [ + s("div", b, [ + s("section", null, [ c(t.$slots, "body", {}, void 0, !0) ]) ]), - o("footer", { + s("footer", { class: r(i.footerClass) }, [ - o("div", x, [ + s("div", x, [ c(t.$slots, "footer", {}, void 0, !0) ]), - o("div", _, [ + s("div", _, [ c(t.$slots, "buttons", {}, () => [ - o("button", { + s("button", { type: "button", class: r(n.cancelButtonClass), onClick: e[1] || (e[1] = (...a) => i.cancelButtonClicked && i.cancelButtonClicked(...a)) - }, y(n.cancelButtonText), 3), + }, k(n.cancelButtonText), 3), n.showConfirmButton ? (l(), d("button", { key: 0, type: "button", class: r(n.confirmButtonClass), onClick: e[2] || (e[2] = (...a) => i.confirm && i.confirm(...a)) - }, y(n.confirmButtonText), 3)) : u("", !0) + }, k(n.confirmButtonText), 3)) : u("", !0) ], !0) ]) ], 2) ], 4)), [ - [g, s.show] + [g, o.show] ]) : u("", !0) ]), _: 3 }, 8, ["name"]) ]); } -const M = /* @__PURE__ */ B(b, [["render", v], ["__scopeId", "data-v-3a19ad3a"]]); +const O = /* @__PURE__ */ B(w, [["render", v], ["__scopeId", "data-v-8c6374f0"]]); export { - M as VueModal + O as VueModal }; diff --git a/dist/vue-modal.umd.cjs b/dist/vue-modal.umd.cjs index ae93aac..a9cb6bc 100644 --- a/dist/vue-modal.umd.cjs +++ b/dist/vue-modal.umd.cjs @@ -1 +1 @@ -(function(a,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],t):(a=typeof globalThis<"u"?globalThis:a||self,t(a.VueModal={},a.Vue))})(this,function(a,t){"use strict";const y="",r=(e,n)=>{const o=e.__vccOpts||e;for(const[d,s]of n)o[d]=s;return o},c={name:"VueModal",props:{confirmButtonText:{type:String,default:"Confirm"},confirmButtonClass:{type:String,default:"btn btn-primary btn-large"},closeOnOutsideClick:{type:Boolean,default:!0},showConfirmButton:{type:Boolean,default:!0},cancelButtonText:{type:String,default:"Cancel"},cancelButtonClass:{type:String,default:"btn btn-danger btn-large mr-2"},closeOnButtonClick:{type:Boolean,default:!0},animation:{type:String,default:"zoom"},timeout:{type:Number,default:0},stickyFooter:{type:Boolean,default:!1},stickyHeader:{type:Boolean,default:!1},width:{type:String,default:"700px"},maxHeight:{type:String,default:"75%"}},data(){return{initiated:!1,show:!1}},created(){window.addEventListener("keydown",e=>{(e.key==="Escape"||e.key==="Esc"||e.key===27)&&this.handleOutsideClick()})},watch:{show(e){e&&this.timeout>0&&setTimeout(()=>{this.closeModal()},this.timeout)}},computed:{animate(){return["zoom","bounce","fade"].includes(this.animation)},modalTransition(){return this.animate?this.animation:""},backdropTransition(){return this.animate?"fade":""},headerClass(){return this.stickyHeader?"--sticky":""},footerClass(){return this.stickyFooter?"--sticky":""},computedWidth(){const e=["px","%","em","rem"];for(let n=0;n[s.show?(t.openBlock(),t.createElementBlock("div",{key:0,class:"modal-backdrop",onClick:n[0]||(n[0]=(...l)=>i.handleOutsideClick&&i.handleOutsideClick(...l))})):t.createCommentVNode("",!0)]),_:1},8,["name"]),t.createVNode(t.Transition,{name:i.modalTransition},{default:t.withCtx(()=>[s.initiated?t.withDirectives((t.openBlock(),t.createElementBlock("div",{key:0,class:"modal",style:t.normalizeStyle({width:i.computedWidth,"max-height":i.computedMaxHeight})},[t.createElementVNode("header",{class:t.normalizeClass(i.headerClass)},[t.renderSlot(e.$slots,"header",{},void 0,!0)],2),t.createElementVNode("div",m,[t.createElementVNode("section",null,[t.renderSlot(e.$slots,"body",{},void 0,!0)])]),t.createElementVNode("footer",{class:t.normalizeClass(i.footerClass)},[t.createElementVNode("div",h,[t.renderSlot(e.$slots,"footer",{},void 0,!0)]),t.createElementVNode("div",u,[t.renderSlot(e.$slots,"buttons",{},()=>[t.createElementVNode("button",{type:"button",class:t.normalizeClass(o.cancelButtonClass),onClick:n[1]||(n[1]=(...l)=>i.cancelButtonClicked&&i.cancelButtonClicked(...l))},t.toDisplayString(o.cancelButtonText),3),o.showConfirmButton?(t.openBlock(),t.createElementBlock("button",{key:0,type:"button",class:t.normalizeClass(o.confirmButtonClass),onClick:n[2]||(n[2]=(...l)=>i.confirm&&i.confirm(...l))},t.toDisplayString(o.confirmButtonText),3)):t.createCommentVNode("",!0)],!0)])],2)],4)),[[t.vShow,s.show]]):t.createCommentVNode("",!0)]),_:3},8,["name"])])}const k=r(c,[["render",f],["__scopeId","data-v-3a19ad3a"]]);a.VueModal=k,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})}); +(function(s,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(s=typeof globalThis<"u"?globalThis:s||self,e(s.VueModal={},s.Vue))})(this,function(s,e){"use strict";const y="",r=(t,n)=>{const o=t.__vccOpts||t;for(const[d,l]of n)o[d]=l;return o},c={name:"VueModal",props:{confirmButtonText:{type:String,default:"Confirm"},confirmButtonClass:{type:String,default:"btn btn-primary btn-large"},closeOnOutsideClick:{type:Boolean,default:!0},showConfirmButton:{type:Boolean,default:!0},cancelButtonText:{type:String,default:"Cancel"},cancelButtonClass:{type:String,default:"btn btn-danger btn-large mr-2"},closeOnButtonClick:{type:Boolean,default:!0},animation:{type:String,default:"zoom"},timeout:{type:Number,default:0},stickyFooter:{type:Boolean,default:!1},stickyHeader:{type:Boolean,default:!1},width:{type:String,default:"700px"},maxHeight:{type:String,default:"75%"},escClosesModal:{type:Boolean,default:!0}},data(){return{initiated:!1,show:!1}},created(){},watch:{show(t){t&&this.timeout>0&&setTimeout(()=>{this.closeModal()},this.timeout)}},computed:{animate(){return["zoom","bounce","fade"].includes(this.animation)},modalTransition(){return this.animate?this.animation:""},backdropTransition(){return this.animate?"fade":""},headerClass(){return this.stickyHeader?"--sticky":""},footerClass(){return this.stickyFooter?"--sticky":""},computedWidth(){const t=["px","%","em","rem"];for(let n=0;n[l.show?(e.openBlock(),e.createElementBlock("div",{key:0,class:"modal-backdrop",onClick:n[0]||(n[0]=(...a)=>i.handleOutsideClick&&i.handleOutsideClick(...a))})):e.createCommentVNode("",!0)]),_:1},8,["name"]),e.createVNode(e.Transition,{name:i.modalTransition},{default:e.withCtx(()=>[l.initiated?e.withDirectives((e.openBlock(),e.createElementBlock("div",{key:0,class:"modal",style:e.normalizeStyle({width:i.computedWidth,"max-height":i.computedMaxHeight})},[e.createElementVNode("header",{class:e.normalizeClass(i.headerClass)},[e.renderSlot(t.$slots,"header",{},void 0,!0)],2),e.createElementVNode("div",m,[e.createElementVNode("section",null,[e.renderSlot(t.$slots,"body",{},void 0,!0)])]),e.createElementVNode("footer",{class:e.normalizeClass(i.footerClass)},[e.createElementVNode("div",h,[e.renderSlot(t.$slots,"footer",{},void 0,!0)]),e.createElementVNode("div",u,[e.renderSlot(t.$slots,"buttons",{},()=>[e.createElementVNode("button",{type:"button",class:e.normalizeClass(o.cancelButtonClass),onClick:n[1]||(n[1]=(...a)=>i.cancelButtonClicked&&i.cancelButtonClicked(...a))},e.toDisplayString(o.cancelButtonText),3),o.showConfirmButton?(e.openBlock(),e.createElementBlock("button",{key:0,type:"button",class:e.normalizeClass(o.confirmButtonClass),onClick:n[2]||(n[2]=(...a)=>i.confirm&&i.confirm(...a))},e.toDisplayString(o.confirmButtonText),3)):e.createCommentVNode("",!0)],!0)])],2)],4)),[[e.vShow,l.show]]):e.createCommentVNode("",!0)]),_:3},8,["name"])])}const k=r(c,[["render",f],["__scopeId","data-v-8c6374f0"]]);s.VueModal=k,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})}); diff --git a/package.json b/package.json index 840299c..bff5f80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@appoly/vue-modal", - "version": "3.0.0", + "version": "3.0.1", "description": "A simple modal component built with Vue.js", "type": "module", "files": [ From fca5bcec9eea840a2d7d74b54d118726f31f6e15 Mon Sep 17 00:00:00 2001 From: Nathan James Date: Fri, 30 Jun 2023 14:53:58 +0100 Subject: [PATCH 3/4] Add new prop to README --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 837091f..b349670 100644 --- a/README.md +++ b/README.md @@ -24,17 +24,18 @@ npm install @appoly/vue-modal | :-------------------- | :------- | :------ | :------------------------------------------------------------------------------------------------- | | `confirmButtonText` | `string` | Confirm | Text displayed on the confirm button | | `confirmButtonClass` | `string` | | Custom class for the confirm button | -| `closeOnOutsideClick` | `bool` | `True` | Close the modal by clicking on the outside | -| `showConfirmButton` | `string` | `True` | Display the confirm button | +| `closeOnOutsideClick` | `bool` | `true` | Close the modal by clicking on the outside | +| `showConfirmButton` | `string` | `true` | Display the confirm button | | `cancelButtonText` | `string` | Cancel | Text displayed on the cancel button | | `cancelButtonClass` | `string` | | Custom class for the cancel button | -| `closeOnButtonClick` | `bool` | `True` | Modal can be closed on cancel/confirm click or an event is emitted and can be closed via functions | +| `closeOnButtonClick` | `bool` | `true` | Modal can be closed on cancel/confirm click or an event is emitted and can be closed via functions | +| `escClosesModal` | `bool` | `true` | Should the modal close if the Esc key is pressed (and `closeOnOutsideClick` is True) | | `animation` | `string` | `zoom` | Animation type, options include `zoom, bounce, fade & none` | | `timeout` | `number` | `0` | Should the modal automatically close, time set in milliseconds | | `width` | `string` | `700px` | Width of the modal in px, rem, em, %. Just numbers default to px | | `maxHeight` | `string` | `75%` | Height of the modal in px, rem, em, %. Just number default to px | -| `sticky-header` | `bool` | `False` | Should the modal have a sticky header | -| `sticky-footer` | `bool` | `False` | Should the modal have a sticky footer | +| `sticky-header` | `bool` | `false` | Should the modal have a sticky header | +| `sticky-footer` | `bool` | `false` | Should the modal have a sticky footer | ## Slots From adc07e4b085de5b97190ba46f918c374a76561dd Mon Sep 17 00:00:00 2001 From: Nathan James Date: Fri, 30 Jun 2023 14:55:52 +0100 Subject: [PATCH 4/4] Tidy up (no longer need this) --- src/components/VueModal.vue | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/VueModal.vue b/src/components/VueModal.vue index d2ad70a..42da078 100644 --- a/src/components/VueModal.vue +++ b/src/components/VueModal.vue @@ -102,9 +102,6 @@ export default { show: false, }; }, - created() { - //listen for esc key press - }, watch: { show(newValue) { if (newValue) {