diff --git a/config/wire-elements-modal.php b/config/wire-elements-modal.php index 2950291..32befb4 100644 --- a/config/wire-elements-modal.php +++ b/config/wire-elements-modal.php @@ -26,6 +26,17 @@ */ 'include_js' => true, + /* + |-------------------------------------------------------------------------- + | Use bootstrap v3 + |-------------------------------------------------------------------------- + | + | It will use view template and JS that supports bootstrap v3. + | + | + */ + 'bootstrap_3' => false, + /* |-------------------------------------------------------------------------- | Modal Component Defaults diff --git a/mix-manifest.json b/mix-manifest.json index 11f2ac3..2de2ed9 100644 --- a/mix-manifest.json +++ b/mix-manifest.json @@ -1,4 +1,5 @@ { "/public/modal.js": "/public/modal.js", + "/public/modal-bootstrap3.js": "/public/modal-bootstrap3.js", "/public/modal.css": "/public/modal.css" } diff --git a/public/modal-bootstrap3.js b/public/modal-bootstrap3.js new file mode 100644 index 0000000..818b870 --- /dev/null +++ b/public/modal-bootstrap3.js @@ -0,0 +1 @@ +(()=>{function t(t){return function(t){if(Array.isArray(t))return e(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,o){if(!t)return;if("string"==typeof t)return e(t,o);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return e(t,o)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function e(t,e){(null==e||e>t.length)&&(e=t.length);for(var o=0,n=new Array(e);o0&&void 0!==arguments[0]&&arguments[0],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!1!==this.show){if(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.dispatch("modalClosed",{name:n})}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.dispatch("destroyComponent",{id:this.activeComponent}),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.setShowPropertyTo(!0),this.activeComponent!==t){!1!==this.activeComponent&&!1===o&&this.componentHistory.push(this.activeComponent);var n=50;!1===this.activeComponent?(this.activeComponent=t,this.showActiveComponent=!0,this.modalWidth=this.getActiveComponentModalAttribute("maxWidthClass")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth=e.getActiveComponentModalAttribute("maxWidthClass")}),300)),this.$nextTick((function(){var o,i=null===(o=e.$refs[t])||void 0===o?void 0:o.querySelector("[autofocus]");i&&setTimeout((function(){i.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input:not([type='hidden'], textarea, select, details, [tabindex]:not([tabindex='-1']))")).filter((function(t){return!t.hasAttribute("disabled")}))},firstFocusable:function(){return this.focusables()[0]},lastFocusable:function(){return this.focusables().slice(-1)[0]},nextFocusable:function(){return this.focusables()[this.nextFocusableIndex()]||this.firstFocusable()},prevFocusable:function(){return this.focusables()[this.prevFocusableIndex()]||this.lastFocusable()},nextFocusableIndex:function(){return(this.focusables().indexOf(document.activeElement)+1)%(this.focusables().length+1)},prevFocusableIndex:function(){return Math.max(0,this.focusables().indexOf(document.activeElement))-1},setShowPropertyTo:function(t){var e=this;this.show=t,t?document.body.classList.add("modal-open"):(document.body.classList.remove("modal-open"),setTimeout((function(){e.activeComponent=!1,e.$wire.resetState()}),300))},init:function(){var t=this;this.modalWidth=this.getActiveComponentModalAttribute("maxWidthClass"),this.listeners.push(Livewire.on("closeModal",(function(e){var o,n,i;t.closeModal(null!==(o=null==e?void 0:e.force)&&void 0!==o&&o,null!==(n=null==e?void 0:e.skipPreviousModals)&&void 0!==n?n:0,null!==(i=null==e?void 0:e.destroySkipped)&&void 0!==i&&i)}))),this.listeners.push(Livewire.on("activeModalComponentChanged",(function(e){var o=e.id;t.setActiveModalComponent(o)})))},destroy:function(){this.listeners.forEach((function(t){t()}))}}}})(); \ No newline at end of file diff --git a/public/modal.js b/public/modal.js index ab2e9d7..416b68f 100644 --- a/public/modal.js +++ b/public/modal.js @@ -1 +1 @@ -(()=>{var t,e={331:()=>{function t(t){return function(t){if(Array.isArray(t))return e(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,o){if(!t)return;if("string"==typeof t)return e(t,o);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return e(t,o)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function e(t,e){(null==e||e>t.length)&&(e=t.length);for(var o=0,n=new Array(e);o0&&void 0!==arguments[0]&&arguments[0],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!1!==this.show){if(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.dispatch("modalClosed",{name:n})}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.dispatch("destroyComponent",{id:this.activeComponent}),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.setShowPropertyTo(!0),this.activeComponent!==t){!1!==this.activeComponent&&!1===o&&this.componentHistory.push(this.activeComponent);var n=50;!1===this.activeComponent?(this.activeComponent=t,this.showActiveComponent=!0,this.modalWidth=this.getActiveComponentModalAttribute("maxWidthClass")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth=e.getActiveComponentModalAttribute("maxWidthClass")}),300)),this.$nextTick((function(){var o,i=null===(o=e.$refs[t])||void 0===o?void 0:o.querySelector("[autofocus]");i&&setTimeout((function(){i.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input:not([type='hidden'], textarea, select, details, [tabindex]:not([tabindex='-1']))")).filter((function(t){return!t.hasAttribute("disabled")}))},firstFocusable:function(){return this.focusables()[0]},lastFocusable:function(){return this.focusables().slice(-1)[0]},nextFocusable:function(){return this.focusables()[this.nextFocusableIndex()]||this.firstFocusable()},prevFocusable:function(){return this.focusables()[this.prevFocusableIndex()]||this.lastFocusable()},nextFocusableIndex:function(){return(this.focusables().indexOf(document.activeElement)+1)%(this.focusables().length+1)},prevFocusableIndex:function(){return Math.max(0,this.focusables().indexOf(document.activeElement))-1},setShowPropertyTo:function(t){var e=this;this.show=t,t?document.body.classList.add("modal-open"):(document.body.classList.remove("modal-open"),setTimeout((function(){e.activeComponent=!1,e.$wire.resetState()}),300))},init:function(){var t=this;this.modalWidth=this.getActiveComponentModalAttribute("maxWidthClass"),this.listeners.push(Livewire.on("closeModal",(function(e){var o,n,i;t.closeModal(null!==(o=null==e?void 0:e.force)&&void 0!==o&&o,null!==(n=null==e?void 0:e.skipPreviousModals)&&void 0!==n?n:0,null!==(i=null==e?void 0:e.destroySkipped)&&void 0!==i&&i)}))),this.listeners.push(Livewire.on("activeModalComponentChanged",(function(e){var o=e.id;t.setActiveModalComponent(o)})))},destroy:function(){this.listeners.forEach((function(t){t()}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var s=o[t]={exports:{}};return e[t](s,s.exports,n),s.exports}n.m=e,t=[],n.O=(e,o,i,s)=>{if(!o){var r=1/0;for(u=0;u=s)&&Object.keys(n.O).every((t=>n.O[t](o[c])))?o.splice(c--,1):(a=!1,s0&&t[u-1][2]>s;u--)t[u]=t[u-1];t[u]=[o,i,s]},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{var t={387:0,109:0};n.O.j=e=>0===t[e];var e=(e,o)=>{var i,s,[r,a,c]=o,l=0;if(r.some((e=>0!==t[e]))){for(i in a)n.o(a,i)&&(n.m[i]=a[i]);if(c)var u=c(n)}for(e&&e(o);ln(331)));var i=n.O(void 0,[109],(()=>n(754)));i=n.O(i)})(); \ No newline at end of file +(()=>{var t,e={331:()=>{function t(t){return function(t){if(Array.isArray(t))return e(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,o){if(!t)return;if("string"==typeof t)return e(t,o);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return e(t,o)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function e(t,e){(null==e||e>t.length)&&(e=t.length);for(var o=0,n=new Array(e);o0&&void 0!==arguments[0]&&arguments[0],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!1!==this.show){if(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.dispatch("modalClosed",{name:n})}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.dispatch("destroyComponent",{id:this.activeComponent}),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.setShowPropertyTo(!0),this.activeComponent!==t){!1!==this.activeComponent&&!1===o&&this.componentHistory.push(this.activeComponent);var n=50;!1===this.activeComponent?(this.activeComponent=t,this.showActiveComponent=!0,this.modalWidth=this.getActiveComponentModalAttribute("maxWidthClass")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth=e.getActiveComponentModalAttribute("maxWidthClass")}),300)),this.$nextTick((function(){var o,i=null===(o=e.$refs[t])||void 0===o?void 0:o.querySelector("[autofocus]");i&&setTimeout((function(){i.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input:not([type='hidden'], textarea, select, details, [tabindex]:not([tabindex='-1']))")).filter((function(t){return!t.hasAttribute("disabled")}))},firstFocusable:function(){return this.focusables()[0]},lastFocusable:function(){return this.focusables().slice(-1)[0]},nextFocusable:function(){return this.focusables()[this.nextFocusableIndex()]||this.firstFocusable()},prevFocusable:function(){return this.focusables()[this.prevFocusableIndex()]||this.lastFocusable()},nextFocusableIndex:function(){return(this.focusables().indexOf(document.activeElement)+1)%(this.focusables().length+1)},prevFocusableIndex:function(){return Math.max(0,this.focusables().indexOf(document.activeElement))-1},setShowPropertyTo:function(t){var e=this;this.show=t,t?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){e.activeComponent=!1,e.$wire.resetState()}),300))},init:function(){var t=this;this.modalWidth=this.getActiveComponentModalAttribute("maxWidthClass"),this.listeners.push(Livewire.on("closeModal",(function(e){var o,n,i;t.closeModal(null!==(o=null==e?void 0:e.force)&&void 0!==o&&o,null!==(n=null==e?void 0:e.skipPreviousModals)&&void 0!==n?n:0,null!==(i=null==e?void 0:e.destroySkipped)&&void 0!==i&&i)}))),this.listeners.push(Livewire.on("activeModalComponentChanged",(function(e){var o=e.id;t.setActiveModalComponent(o)})))},destroy:function(){this.listeners.forEach((function(t){t()}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var s=o[t]={exports:{}};return e[t](s,s.exports,n),s.exports}n.m=e,t=[],n.O=(e,o,i,s)=>{if(!o){var r=1/0;for(u=0;u=s)&&Object.keys(n.O).every((t=>n.O[t](o[c])))?o.splice(c--,1):(a=!1,s0&&t[u-1][2]>s;u--)t[u]=t[u-1];t[u]=[o,i,s]},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{var t={387:0,109:0};n.O.j=e=>0===t[e];var e=(e,o)=>{var i,s,[r,a,c]=o,l=0;if(r.some((e=>0!==t[e]))){for(i in a)n.o(a,i)&&(n.m[i]=a[i]);if(c)var u=c(n)}for(e&&e(o);ln(331)));var i=n.O(void 0,[109],(()=>n(754)));i=n.O(i)})(); \ No newline at end of file diff --git a/resources/js/modal-bootstrap3.js b/resources/js/modal-bootstrap3.js new file mode 100644 index 0000000..8bf55f0 --- /dev/null +++ b/resources/js/modal-bootstrap3.js @@ -0,0 +1,182 @@ +window.LivewireUIModal = () => { + return { + show: false, + showActiveComponent: true, + activeComponent: false, + componentHistory: [], + modalWidth: null , + listeners: [], + getActiveComponentModalAttribute(key) { + if (this.$wire.get('components')[this.activeComponent] !== undefined) { + return this.$wire.get('components')[this.activeComponent]['modalAttributes'][key]; + } + }, + closeModalOnEscape(trigger) { + if (this.getActiveComponentModalAttribute('closeOnEscape') === false) { + return; + } + + if (!this.closingModal('closingModalOnEscape')) { + return; + } + + let force = this.getActiveComponentModalAttribute('closeOnEscapeIsForceful') === true; + this.closeModal(force); + }, + closeModalOnClickAway(trigger) { + if (this.getActiveComponentModalAttribute('closeOnClickAway') === false) { + return; + } + + if (!this.closingModal('closingModalOnClickAway')) { + return; + } + + this.closeModal(true); + }, + closingModal(eventName) { + const componentName = this.$wire.get('components')[this.activeComponent].name; + + var params = { + id: this.activeComponent, + closing: true, + }; + + Livewire.dispatchTo(componentName, eventName, params); + + return params.closing; + }, + closeModal(force = false, skipPreviousModals = 0, destroySkipped = false) { + if(this.show === false) { + return; + } + + if (this.getActiveComponentModalAttribute('dispatchCloseEvent') === true) { + const componentName = this.$wire.get('components')[this.activeComponent].name; + Livewire.dispatch('modalClosed', {name: componentName}); + } + + if (this.getActiveComponentModalAttribute('destroyOnClose') === true) { + Livewire.dispatch('destroyComponent', {id: this.activeComponent}); + } + + if (skipPreviousModals > 0) { + for (var i = 0; i < skipPreviousModals; i++) { + if (destroySkipped) { + const id = this.componentHistory[this.componentHistory.length - 1]; + Livewire.dispatch('destroyComponent', {id: id}); + } + this.componentHistory.pop(); + } + } + + const id = this.componentHistory.pop(); + + if (id && !force) { + if (id) { + this.setActiveModalComponent(id, true); + } else { + this.setShowPropertyTo(false); + } + } else { + this.setShowPropertyTo(false); + } + }, + setActiveModalComponent(id, skip = false) { + this.setShowPropertyTo(true); + + if (this.activeComponent === id) { + return; + } + + if (this.activeComponent !== false && skip === false) { + this.componentHistory.push(this.activeComponent); + } + + let focusableTimeout = 50; + + if (this.activeComponent === false) { + this.activeComponent = id + this.showActiveComponent = true; + this.modalWidth = this.getActiveComponentModalAttribute('maxWidthClass'); + } else { + this.showActiveComponent = false; + + focusableTimeout = 400; + + setTimeout(() => { + this.activeComponent = id; + this.showActiveComponent = true; + this.modalWidth = this.getActiveComponentModalAttribute('maxWidthClass'); + }, 300); + } + + this.$nextTick(() => { + let focusable = this.$refs[id]?.querySelector('[autofocus]'); + if (focusable) { + setTimeout(() => { + focusable.focus(); + }, focusableTimeout); + } + }); + }, + focusables() { + let selector = 'a, button, input:not([type=\'hidden\'], textarea, select, details, [tabindex]:not([tabindex=\'-1\']))' + + return [...this.$el.querySelectorAll(selector)] + .filter(el => !el.hasAttribute('disabled')) + }, + firstFocusable() { + return this.focusables()[0] + }, + lastFocusable() { + return this.focusables().slice(-1)[0] + }, + nextFocusable() { + return this.focusables()[this.nextFocusableIndex()] || this.firstFocusable() + }, + prevFocusable() { + return this.focusables()[this.prevFocusableIndex()] || this.lastFocusable() + }, + nextFocusableIndex() { + return (this.focusables().indexOf(document.activeElement) + 1) % (this.focusables().length + 1) + }, + prevFocusableIndex() { + return Math.max(0, this.focusables().indexOf(document.activeElement)) - 1 + }, + setShowPropertyTo(show) { + this.show = show; + + if (show) { + document.body.classList.add('modal-open'); + } else { + document.body.classList.remove('modal-open'); + + setTimeout(() => { + this.activeComponent = false; + this.$wire.resetState(); + }, 300); + } + }, + init() { + this.modalWidth = this.getActiveComponentModalAttribute('maxWidthClass'); + + this.listeners.push( + Livewire.on('closeModal', (data) => { + this.closeModal(data?.force ?? false, data?.skipPreviousModals ?? 0, data?.destroySkipped ?? false); + }) + ); + + this.listeners.push( + Livewire.on('activeModalComponentChanged', ({id}) => { + this.setActiveModalComponent(id); + }) + ); + }, + destroy() { + this.listeners.forEach((listener) => { + listener(); + }); + } + }; +} diff --git a/resources/js/modal.js b/resources/js/modal.js index 8bf55f0..29a00f0 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -148,9 +148,9 @@ window.LivewireUIModal = () => { this.show = show; if (show) { - document.body.classList.add('modal-open'); + document.body.classList.add('overflow-y-hidden'); } else { - document.body.classList.remove('modal-open'); + document.body.classList.remove('overflow-y-hidden'); setTimeout(() => { this.activeComponent = false; diff --git a/resources/views/modal-bootstrap3.blade.php b/resources/views/modal-bootstrap3.blade.php new file mode 100644 index 0000000..33414cc --- /dev/null +++ b/resources/views/modal-bootstrap3.blade.php @@ -0,0 +1,51 @@ +
+ @isset($jsPath) + + @endisset + @isset($cssPath) + + @endisset +
+ + @teleport('body') + + + @endteleport + + +
+
diff --git a/src/Modal.php b/src/Modal.php index bca3ea9..0d7d09c 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -123,13 +123,22 @@ public function render(): View { if (config('wire-elements-modal.include_js', true)) { $jsPath = __DIR__.'/../public/modal.js'; + if (config('wire-elements-modal.bootstrap_3', false)) { + $jsPath = __DIR__.'/../public/modal-bootstrap3.js'; + } } if (config('wire-elements-modal.include_css', false)) { $cssPath = __DIR__.'/../public/modal.css'; } - return view('wire-elements-modal::modal', [ + $view = 'wire-elements-modal::modal'; + + if (config('wire-elements-modal.bootstrap_3', false)) { + $view = 'wire-elements-modal::modal-bootstrap3'; + } + + return view($view, [ 'jsPath' => $jsPath ?? null, 'cssPath' => $cssPath ?? null, ]); diff --git a/webpack.mix.js b/webpack.mix.js index 913bec9..101ad11 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -1,6 +1,7 @@ const mix = require('laravel-mix'); mix.js('resources/js/modal.js', 'public/') + .js('resources/js/modal-bootstrap3.js', 'public/') .postCss("resources/css/modal.css", "public/", [ require("tailwindcss"), ]);