From 4cf83a53b79fc25c1322505a77e3f3d2ee5b9be0 Mon Sep 17 00:00:00 2001 From: Oliver Musovski Date: Wed, 25 Aug 2021 16:48:39 -0700 Subject: [PATCH 01/21] added remove from stack --- src/Modal.php | 6 ++++++ src/ModalComponent.php | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Modal.php b/src/Modal.php index 0ca5575..0657196 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -47,10 +47,16 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->emit('activeModalComponentChanged', $id); } + public function popComponent() + { + array_pop($this->components); + } + public function getListeners(): array { return [ 'openModal', + 'popComponent' ]; } diff --git a/src/ModalComponent.php b/src/ModalComponent.php index b5c3be8..d38df59 100644 --- a/src/ModalComponent.php +++ b/src/ModalComponent.php @@ -11,6 +11,8 @@ abstract class ModalComponent extends Component implements Contract public int $skipModals = 0; + public bool $removeFromStack = false; + public function skipPreviousModals($count = 1): self { $this->skipPreviousModal($count); @@ -32,9 +34,20 @@ public function forceClose(): self return $this; } + public function removeFromStack(): self + { + $this->removeFromStack = true; + + return $this; + } + public function closeModal(): void { $this->emit('closeModal', $this->forceClose, $this->skipModals); + + if ($this->removeFromStack) { + $this->emit('popComponent', $this->id); + } } public function closeModalWithEvents(array $events): void From 811df706a6f18943f7ae86959f6a87fe91723fc4 Mon Sep 17 00:00:00 2001 From: David Bell Date: Mon, 30 Aug 2021 12:28:27 +1000 Subject: [PATCH 02/21] rename init to initialize for alpinejs 2 and 3 compat --- resources/js/modal.js | 2 +- resources/views/modal.blade.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/js/modal.js b/resources/js/modal.js index c482e10..4ba67de 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -112,7 +112,7 @@ window.LivewireUIModal = () => { prevFocusableIndex() { return Math.max(0, this.focusables().indexOf(document.activeElement)) - 1 }, - init() { + initialize() { this.$watch('show', value => { if (value) { document.body.classList.add('overflow-y-hidden'); diff --git a/resources/views/modal.blade.php b/resources/views/modal.blade.php index ef62b2b..bc94db5 100644 --- a/resources/views/modal.blade.php +++ b/resources/views/modal.blade.php @@ -8,7 +8,7 @@
Date: Mon, 30 Aug 2021 12:52:47 +1000 Subject: [PATCH 03/21] support for destroyComponent, destroy on close and destroySkipped --- config/livewire-ui-modal.php | 2 ++ resources/js/modal.js | 31 ++++++++++++++++++++++++++++++- resources/views/modal.blade.php | 2 +- src/Modal.php | 7 ++++--- src/ModalComponent.php | 32 +++++++++++++++++--------------- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/config/livewire-ui-modal.php b/config/livewire-ui-modal.php index 8804c94..a7cb744 100644 --- a/config/livewire-ui-modal.php +++ b/config/livewire-ui-modal.php @@ -48,5 +48,7 @@ 'close_modal_on_escape_is_forceful' => true, 'dispatch_close_event' => false, + + 'destroy_on_close' => false, ], ]; diff --git a/resources/js/modal.js b/resources/js/modal.js index 4ba67de..de3032f 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -25,15 +25,23 @@ window.LivewireUIModal = () => { this.closeModal(true); }, - closeModal(force = false, skipPreviousModals = 0) { + closeModal(force = false, skipPreviousModals = 0, destroySkipped = false) { if (this.getActiveComponentModalAttribute('dispatchCloseEvent') === true) { const componentName = this.$wire.get('components')[this.activeComponent].name; Livewire.emit('modalClosed', componentName); } + if (this.getActiveComponentModalAttribute('destroyOnClose') === true) { + Livewire.emit('componentDestroyed', this.activeComponent); + } + if (skipPreviousModals > 0) { for (var i = 0; i < skipPreviousModals; i++) { + if (destroySkipped) { + const id = this.componentHistory[this.componentHistory.length - 1]; + Livewire.emit('componentDestroyed', id); + } this.componentHistory.pop(); } } @@ -133,6 +141,27 @@ window.LivewireUIModal = () => { Livewire.on('activeModalComponentChanged', (id) => { this.setActiveModalComponent(id); }); + + Livewire.on('destroyComponent', (name) => { + let components = this.$wire.get('components'); + let component = Object.getOwnPropertyNames(components).filter(id => { + return components[id].name === name; + }); + + let id = component[0]; + + if (id == this.activeComponent) { + this.closeModal() + Livewire.emit('componentDestroyed', id); + } else { + this.componentHistory = this.componentHistory.filter(componentId => { + return componentId !== id; + }); + + Livewire.emit('componentDestroyed', id); + } + + }); } }; } diff --git a/resources/views/modal.blade.php b/resources/views/modal.blade.php index bc94db5..9c26396 100644 --- a/resources/views/modal.blade.php +++ b/resources/views/modal.blade.php @@ -46,7 +46,7 @@ class="fixed inset-0 transition-all transform" class="inline-block w-full align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:w-full" > @forelse($components as $id => $component) -
+
@livewire($component['name'], $component['attributes'], key($id))
@empty diff --git a/src/Modal.php b/src/Modal.php index 0657196..f91b3e1 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -38,6 +38,7 @@ public function openModal($component, $componentAttributes = [], $modalAttribute 'closeOnEscape' => $componentClass::closeModalOnEscape(), 'closeOnEscapeIsForceful' => $componentClass::closeModalOnEscapeIsForceful(), 'dispatchCloseEvent' => $componentClass::dispatchCloseEvent(), + 'destroyOnClose' => $componentClass::destroyOnClose(), 'maxWidth' => $componentClass::modalMaxWidth(), ], $modalAttributes), ]; @@ -47,16 +48,16 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->emit('activeModalComponentChanged', $id); } - public function popComponent() + public function componentDestroyed($id): void { - array_pop($this->components); + unset($this->components[$id]); } public function getListeners(): array { return [ 'openModal', - 'popComponent' + 'componentDestroyed' ]; } diff --git a/src/ModalComponent.php b/src/ModalComponent.php index d38df59..e1643f1 100644 --- a/src/ModalComponent.php +++ b/src/ModalComponent.php @@ -11,43 +11,40 @@ abstract class ModalComponent extends Component implements Contract public int $skipModals = 0; - public bool $removeFromStack = false; + public bool $destroySkipped = false; - public function skipPreviousModals($count = 1): self + public function destroySkippedModals(): self { - $this->skipPreviousModal($count); - + $this->destroySkipped = true; + return $this; } - public function skipPreviousModal($count = 1): self + public function skipPreviousModals($count = 1, $destroy = false): self { - $this->skipModals = $count; + $this->skipPreviousModal($count, $destroy); return $this; } - public function forceClose(): self + public function skipPreviousModal($count = 1, $destroy = false): self { - $this->forceClose = true; + $this->skipModals = $count; + $this->destroySkipped = $destroy; return $this; } - public function removeFromStack(): self + public function forceClose(): self { - $this->removeFromStack = true; + $this->forceClose = true; return $this; } public function closeModal(): void { - $this->emit('closeModal', $this->forceClose, $this->skipModals); - - if ($this->removeFromStack) { - $this->emit('popComponent', $this->id); - } + $this->emit('closeModal', $this->forceClose, $this->skipModals, $this->destroySkipped); } public function closeModalWithEvents(array $events): void @@ -81,6 +78,11 @@ public static function dispatchCloseEvent(): bool return config('livewire-ui-modal.component_defaults.dispatch_close_event', false); } + public static function destroyOnClose(): bool + { + return config('livewire-ui-modal.component_defaults.destroy_on_close', false); + } + private function emitModalEvents(array $events): void { foreach ($events as $component => $event) { From 59e33c40209e94b60503cc53c6cdf24d39589719 Mon Sep 17 00:00:00 2001 From: David Bell Date: Mon, 30 Aug 2021 13:00:56 +1000 Subject: [PATCH 04/21] build production --- public/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/modal.js b/public/modal.js index e6ddf28..27fadc0 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;if(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var o=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",o)}if(e>0)for(var n=0;n1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},init:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;t.closeModal(e,o)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[c])))?o.splice(c--,1):(a=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,a,c]=o,l=0;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(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",n)}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.emit("componentDestroyed",this.activeComponent),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},initialize:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;t.closeModal(e,o)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)})),Livewire.on("destroyComponent",(function(e){var o=t.$wire.get("components"),n=Object.getOwnPropertyNames(o).filter((function(t){return o[t].name===e}))[0];n==t.activeComponent?(t.closeModal(),Livewire.emit("componentDestroyed",n)):(t.componentHistory=t.componentHistory.filter((function(t){return t!==n})),Livewire.emit("componentDestroyed",n))}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[a])))?o.splice(a--,1):(c=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,c,a]=o,l=0;for(i in c)n.o(c,i)&&(n.m[i]=c[i]);if(a)var u=a(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 From a2dbff1d55c9dd319986994a5fc3107af5eba5c1 Mon Sep 17 00:00:00 2001 From: David Bell Date: Tue, 31 Aug 2021 08:27:25 +1000 Subject: [PATCH 05/21] updated closeModal parameters --- resources/js/modal.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/js/modal.js b/resources/js/modal.js index de3032f..44e7766 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -134,8 +134,8 @@ window.LivewireUIModal = () => { } }); - Livewire.on('closeModal', (force = false, skipPreviousModals = 0) => { - this.closeModal(force, skipPreviousModals); + Livewire.on('closeModal', (force = false, skipPreviousModals = 0, destroySkipped = false) => { + this.closeModal(force, skipPreviousModals, destroySkipped); }); Livewire.on('activeModalComponentChanged', (id) => { @@ -157,7 +157,7 @@ window.LivewireUIModal = () => { this.componentHistory = this.componentHistory.filter(componentId => { return componentId !== id; }); - + Livewire.emit('componentDestroyed', id); } From 2336e92c10186f5f9bb045c174121953b4dcd894 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 10:52:47 +1000 Subject: [PATCH 06/21] removed destroyComponent alpine listeners --- resources/js/modal.js | 25 +++---------------------- src/Modal.php | 4 ++-- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/resources/js/modal.js b/resources/js/modal.js index 44e7766..bfebb5d 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -33,14 +33,14 @@ window.LivewireUIModal = () => { } if (this.getActiveComponentModalAttribute('destroyOnClose') === true) { - Livewire.emit('componentDestroyed', this.activeComponent); + Livewire.emit('destroyComponent', this.activeComponent); } if (skipPreviousModals > 0) { for (var i = 0; i < skipPreviousModals; i++) { if (destroySkipped) { const id = this.componentHistory[this.componentHistory.length - 1]; - Livewire.emit('componentDestroyed', id); + Livewire.emit('destroyComponent', id); } this.componentHistory.pop(); } @@ -142,26 +142,7 @@ window.LivewireUIModal = () => { this.setActiveModalComponent(id); }); - Livewire.on('destroyComponent', (name) => { - let components = this.$wire.get('components'); - let component = Object.getOwnPropertyNames(components).filter(id => { - return components[id].name === name; - }); - - let id = component[0]; - - if (id == this.activeComponent) { - this.closeModal() - Livewire.emit('componentDestroyed', id); - } else { - this.componentHistory = this.componentHistory.filter(componentId => { - return componentId !== id; - }); - - Livewire.emit('componentDestroyed', id); - } - - }); + } }; } diff --git a/src/Modal.php b/src/Modal.php index f91b3e1..95223da 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -48,7 +48,7 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->emit('activeModalComponentChanged', $id); } - public function componentDestroyed($id): void + public function destroyComponent($id): void { unset($this->components[$id]); } @@ -57,7 +57,7 @@ public function getListeners(): array { return [ 'openModal', - 'componentDestroyed' + 'destroyComponent' ]; } From c596b5266d52a01e9af5fc2383828ae2389b2271 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 10:53:53 +1000 Subject: [PATCH 07/21] build --- public/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/modal.js b/public/modal.js index 27fadc0..71ee39a 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(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",n)}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.emit("componentDestroyed",this.activeComponent),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},initialize:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;t.closeModal(e,o)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)})),Livewire.on("destroyComponent",(function(e){var o=t.$wire.get("components"),n=Object.getOwnPropertyNames(o).filter((function(t){return o[t].name===e}))[0];n==t.activeComponent?(t.closeModal(),Livewire.emit("componentDestroyed",n)):(t.componentHistory=t.componentHistory.filter((function(t){return t!==n})),Livewire.emit("componentDestroyed",n))}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[a])))?o.splice(a--,1):(c=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,c,a]=o,l=0;for(i in c)n.o(c,i)&&(n.m[i]=c[i]);if(a)var u=a(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(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",n)}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.emit("destroyComponent",this.activeComponent),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},initialize:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];t.closeModal(e,o,n)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[c])))?o.splice(c--,1):(a=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,a,c]=o,l=0;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 From fe7d68da2ce8accb4c9de1bb41e1318b5e5af124 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 11:35:52 +1000 Subject: [PATCH 08/21] added tests --- src/Modal.php | 4 ++++ tests/LivewireModalComponentTest.php | 14 ++++++++---- tests/LivewireModalTest.php | 34 +++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/Modal.php b/src/Modal.php index 95223da..2c77044 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -21,6 +21,7 @@ public function resetState(): void public function openModal($component, $componentAttributes = [], $modalAttributes = []): void { + ray('open modal'); $requiredInterface = \LivewireUI\Modal\Contracts\ModalComponent::class; $componentClass = app('livewire')->getClass($component); $reflect = new ReflectionClass($componentClass); @@ -46,10 +47,13 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->activeComponent = $id; $this->emit('activeModalComponentChanged', $id); + + ray($this->components); } public function destroyComponent($id): void { + ray('destroy component'); unset($this->components[$id]); } diff --git a/tests/LivewireModalComponentTest.php b/tests/LivewireModalComponentTest.php index 4f67c29..f96b53d 100644 --- a/tests/LivewireModalComponentTest.php +++ b/tests/LivewireModalComponentTest.php @@ -11,7 +11,7 @@ public function testCloseModal(): void { Livewire::test(DemoModal::class) ->call('closeModal') - ->assertEmitted('closeModal', false, 0); + ->assertEmitted('closeModal', false, 0, false); } public function testForceCloseModal(): void @@ -19,7 +19,7 @@ public function testForceCloseModal(): void Livewire::test(DemoModal::class) ->call('forceClose') ->call('closeModal') - ->assertEmitted('closeModal', true, 0); + ->assertEmitted('closeModal', true, 0, false); } public function testModalSkipping(): void @@ -27,12 +27,18 @@ public function testModalSkipping(): void Livewire::test(DemoModal::class) ->call('skipPreviousModals', 5) ->call('closeModal') - ->assertEmitted('closeModal', false, 5); + ->assertEmitted('closeModal', false, 5, false); Livewire::test(DemoModal::class) ->call('skipPreviousModal') ->call('closeModal') - ->assertEmitted('closeModal', false, 1); + ->assertEmitted('closeModal', false, 1, false); + + Livewire::test(DemoModal::class) + ->call('skipPreviousModal') + ->call('destroySkippedModals') + ->call('closeModal') + ->assertEmitted('closeModal', false, 1, true); } public function testModalEventEmitting(): void diff --git a/tests/LivewireModalTest.php b/tests/LivewireModalTest.php index 68659b9..6e31e0d 100644 --- a/tests/LivewireModalTest.php +++ b/tests/LivewireModalTest.php @@ -7,6 +7,8 @@ use LivewireUI\Modal\Tests\Components\DemoModal; use LivewireUI\Modal\Tests\Components\InvalidModal; +use function PHPUnit\Framework\assertArrayNotHasKey; + class LivewireModalTest extends TestCase { public function testOpenModalEventListener(): void @@ -17,7 +19,7 @@ public function testOpenModalEventListener(): void // Event attributes $component = 'demo-modal'; $componentAttributes = ['message' => 'Foobar']; - $modalAttributes = ['hello' => 'world', 'closeOnEscape' => true, 'maxWidth' => '2xl', 'closeOnClickAway' => true, 'closeOnEscapeIsForceful' => true, 'dispatchCloseEvent' => false]; + $modalAttributes = ['hello' => 'world', 'closeOnEscape' => true, 'maxWidth' => '2xl', 'closeOnClickAway' => true, 'closeOnEscapeIsForceful' => true, 'dispatchCloseEvent' => false, 'destroyOnClose' => false]; // Demo modal unique identifier $id = md5($component . serialize($componentAttributes)); @@ -38,6 +40,36 @@ public function testOpenModalEventListener(): void ->assertEmitted('activeModalComponentChanged', $id); } + public function testDestroyComponentEventListener(): void + { + // Demo modal component + Livewire::component('demo-modal', DemoModal::class); + + $component = 'demo-modal'; + $componentAttributes = ['message' => 'Foobar']; + $modalAttributes = ['hello' => 'world', 'closeOnEscape' => true, 'maxWidth' => '2xl', 'closeOnClickAway' => true, 'closeOnEscapeIsForceful' => true, 'dispatchCloseEvent' => false, 'destroyOnClose' => false]; + + // Demo modal unique identifier + $id = md5($component . serialize($componentAttributes)); + + + // Demo modal unique identifier + $id = md5($component . serialize($componentAttributes)); + + Livewire::test(Modal::class) + ->emit('openModal', $component, $componentAttributes, $modalAttributes) + ->assertSet('components', [ + $id => [ + 'name' => $component, + 'attributes' => $componentAttributes, + 'modalAttributes' => $modalAttributes, + ], + ]) + ->emit('destroyComponent', $id) + ->assertSet('components', []); + + } + public function testModalReset(): void { Livewire::component('demo-modal', DemoModal::class); From 23038d712f77329bdd0b217ff862f4b99f14f669 Mon Sep 17 00:00:00 2001 From: Oliver Musovski Date: Wed, 25 Aug 2021 16:48:39 -0700 Subject: [PATCH 09/21] added remove from stack --- src/Modal.php | 6 ++++++ src/ModalComponent.php | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Modal.php b/src/Modal.php index 0ca5575..0657196 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -47,10 +47,16 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->emit('activeModalComponentChanged', $id); } + public function popComponent() + { + array_pop($this->components); + } + public function getListeners(): array { return [ 'openModal', + 'popComponent' ]; } diff --git a/src/ModalComponent.php b/src/ModalComponent.php index b5c3be8..d38df59 100644 --- a/src/ModalComponent.php +++ b/src/ModalComponent.php @@ -11,6 +11,8 @@ abstract class ModalComponent extends Component implements Contract public int $skipModals = 0; + public bool $removeFromStack = false; + public function skipPreviousModals($count = 1): self { $this->skipPreviousModal($count); @@ -32,9 +34,20 @@ public function forceClose(): self return $this; } + public function removeFromStack(): self + { + $this->removeFromStack = true; + + return $this; + } + public function closeModal(): void { $this->emit('closeModal', $this->forceClose, $this->skipModals); + + if ($this->removeFromStack) { + $this->emit('popComponent', $this->id); + } } public function closeModalWithEvents(array $events): void From 5f8d0c3bcc8260c21113df060b7ff306ff2a737c Mon Sep 17 00:00:00 2001 From: David Bell Date: Mon, 30 Aug 2021 12:28:27 +1000 Subject: [PATCH 10/21] rename init to initialize for alpinejs 2 and 3 compat --- resources/js/modal.js | 2 +- resources/views/modal.blade.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/js/modal.js b/resources/js/modal.js index c482e10..4ba67de 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -112,7 +112,7 @@ window.LivewireUIModal = () => { prevFocusableIndex() { return Math.max(0, this.focusables().indexOf(document.activeElement)) - 1 }, - init() { + initialize() { this.$watch('show', value => { if (value) { document.body.classList.add('overflow-y-hidden'); diff --git a/resources/views/modal.blade.php b/resources/views/modal.blade.php index ef62b2b..bc94db5 100644 --- a/resources/views/modal.blade.php +++ b/resources/views/modal.blade.php @@ -8,7 +8,7 @@
Date: Mon, 30 Aug 2021 12:52:47 +1000 Subject: [PATCH 11/21] support for destroyComponent, destroy on close and destroySkipped --- config/livewire-ui-modal.php | 2 ++ resources/js/modal.js | 31 ++++++++++++++++++++++++++++++- resources/views/modal.blade.php | 2 +- src/Modal.php | 7 ++++--- src/ModalComponent.php | 32 +++++++++++++++++--------------- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/config/livewire-ui-modal.php b/config/livewire-ui-modal.php index 8804c94..a7cb744 100644 --- a/config/livewire-ui-modal.php +++ b/config/livewire-ui-modal.php @@ -48,5 +48,7 @@ 'close_modal_on_escape_is_forceful' => true, 'dispatch_close_event' => false, + + 'destroy_on_close' => false, ], ]; diff --git a/resources/js/modal.js b/resources/js/modal.js index 4ba67de..de3032f 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -25,15 +25,23 @@ window.LivewireUIModal = () => { this.closeModal(true); }, - closeModal(force = false, skipPreviousModals = 0) { + closeModal(force = false, skipPreviousModals = 0, destroySkipped = false) { if (this.getActiveComponentModalAttribute('dispatchCloseEvent') === true) { const componentName = this.$wire.get('components')[this.activeComponent].name; Livewire.emit('modalClosed', componentName); } + if (this.getActiveComponentModalAttribute('destroyOnClose') === true) { + Livewire.emit('componentDestroyed', this.activeComponent); + } + if (skipPreviousModals > 0) { for (var i = 0; i < skipPreviousModals; i++) { + if (destroySkipped) { + const id = this.componentHistory[this.componentHistory.length - 1]; + Livewire.emit('componentDestroyed', id); + } this.componentHistory.pop(); } } @@ -133,6 +141,27 @@ window.LivewireUIModal = () => { Livewire.on('activeModalComponentChanged', (id) => { this.setActiveModalComponent(id); }); + + Livewire.on('destroyComponent', (name) => { + let components = this.$wire.get('components'); + let component = Object.getOwnPropertyNames(components).filter(id => { + return components[id].name === name; + }); + + let id = component[0]; + + if (id == this.activeComponent) { + this.closeModal() + Livewire.emit('componentDestroyed', id); + } else { + this.componentHistory = this.componentHistory.filter(componentId => { + return componentId !== id; + }); + + Livewire.emit('componentDestroyed', id); + } + + }); } }; } diff --git a/resources/views/modal.blade.php b/resources/views/modal.blade.php index bc94db5..9c26396 100644 --- a/resources/views/modal.blade.php +++ b/resources/views/modal.blade.php @@ -46,7 +46,7 @@ class="fixed inset-0 transition-all transform" class="inline-block w-full align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:w-full" > @forelse($components as $id => $component) -
+
@livewire($component['name'], $component['attributes'], key($id))
@empty diff --git a/src/Modal.php b/src/Modal.php index 0657196..f91b3e1 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -38,6 +38,7 @@ public function openModal($component, $componentAttributes = [], $modalAttribute 'closeOnEscape' => $componentClass::closeModalOnEscape(), 'closeOnEscapeIsForceful' => $componentClass::closeModalOnEscapeIsForceful(), 'dispatchCloseEvent' => $componentClass::dispatchCloseEvent(), + 'destroyOnClose' => $componentClass::destroyOnClose(), 'maxWidth' => $componentClass::modalMaxWidth(), ], $modalAttributes), ]; @@ -47,16 +48,16 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->emit('activeModalComponentChanged', $id); } - public function popComponent() + public function componentDestroyed($id): void { - array_pop($this->components); + unset($this->components[$id]); } public function getListeners(): array { return [ 'openModal', - 'popComponent' + 'componentDestroyed' ]; } diff --git a/src/ModalComponent.php b/src/ModalComponent.php index d38df59..e1643f1 100644 --- a/src/ModalComponent.php +++ b/src/ModalComponent.php @@ -11,43 +11,40 @@ abstract class ModalComponent extends Component implements Contract public int $skipModals = 0; - public bool $removeFromStack = false; + public bool $destroySkipped = false; - public function skipPreviousModals($count = 1): self + public function destroySkippedModals(): self { - $this->skipPreviousModal($count); - + $this->destroySkipped = true; + return $this; } - public function skipPreviousModal($count = 1): self + public function skipPreviousModals($count = 1, $destroy = false): self { - $this->skipModals = $count; + $this->skipPreviousModal($count, $destroy); return $this; } - public function forceClose(): self + public function skipPreviousModal($count = 1, $destroy = false): self { - $this->forceClose = true; + $this->skipModals = $count; + $this->destroySkipped = $destroy; return $this; } - public function removeFromStack(): self + public function forceClose(): self { - $this->removeFromStack = true; + $this->forceClose = true; return $this; } public function closeModal(): void { - $this->emit('closeModal', $this->forceClose, $this->skipModals); - - if ($this->removeFromStack) { - $this->emit('popComponent', $this->id); - } + $this->emit('closeModal', $this->forceClose, $this->skipModals, $this->destroySkipped); } public function closeModalWithEvents(array $events): void @@ -81,6 +78,11 @@ public static function dispatchCloseEvent(): bool return config('livewire-ui-modal.component_defaults.dispatch_close_event', false); } + public static function destroyOnClose(): bool + { + return config('livewire-ui-modal.component_defaults.destroy_on_close', false); + } + private function emitModalEvents(array $events): void { foreach ($events as $component => $event) { From 360d75810087b420e50c0e75be688690dbfdbdcf Mon Sep 17 00:00:00 2001 From: David Bell Date: Mon, 30 Aug 2021 13:00:56 +1000 Subject: [PATCH 12/21] build production --- public/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/modal.js b/public/modal.js index e6ddf28..27fadc0 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;if(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var o=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",o)}if(e>0)for(var n=0;n1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},init:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;t.closeModal(e,o)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[c])))?o.splice(c--,1):(a=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,a,c]=o,l=0;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(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",n)}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.emit("componentDestroyed",this.activeComponent),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},initialize:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;t.closeModal(e,o)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)})),Livewire.on("destroyComponent",(function(e){var o=t.$wire.get("components"),n=Object.getOwnPropertyNames(o).filter((function(t){return o[t].name===e}))[0];n==t.activeComponent?(t.closeModal(),Livewire.emit("componentDestroyed",n)):(t.componentHistory=t.componentHistory.filter((function(t){return t!==n})),Livewire.emit("componentDestroyed",n))}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[a])))?o.splice(a--,1):(c=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,c,a]=o,l=0;for(i in c)n.o(c,i)&&(n.m[i]=c[i]);if(a)var u=a(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 From d589721b140308da4f18f9d2c58afe904a974256 Mon Sep 17 00:00:00 2001 From: David Bell Date: Tue, 31 Aug 2021 08:27:25 +1000 Subject: [PATCH 13/21] updated closeModal parameters --- resources/js/modal.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/js/modal.js b/resources/js/modal.js index de3032f..44e7766 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -134,8 +134,8 @@ window.LivewireUIModal = () => { } }); - Livewire.on('closeModal', (force = false, skipPreviousModals = 0) => { - this.closeModal(force, skipPreviousModals); + Livewire.on('closeModal', (force = false, skipPreviousModals = 0, destroySkipped = false) => { + this.closeModal(force, skipPreviousModals, destroySkipped); }); Livewire.on('activeModalComponentChanged', (id) => { @@ -157,7 +157,7 @@ window.LivewireUIModal = () => { this.componentHistory = this.componentHistory.filter(componentId => { return componentId !== id; }); - + Livewire.emit('componentDestroyed', id); } From 50c541e9259c48ec5c51454e8019c06294972b81 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 10:52:47 +1000 Subject: [PATCH 14/21] removed destroyComponent alpine listeners --- resources/js/modal.js | 25 +++---------------------- src/Modal.php | 4 ++-- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/resources/js/modal.js b/resources/js/modal.js index 44e7766..bfebb5d 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -33,14 +33,14 @@ window.LivewireUIModal = () => { } if (this.getActiveComponentModalAttribute('destroyOnClose') === true) { - Livewire.emit('componentDestroyed', this.activeComponent); + Livewire.emit('destroyComponent', this.activeComponent); } if (skipPreviousModals > 0) { for (var i = 0; i < skipPreviousModals; i++) { if (destroySkipped) { const id = this.componentHistory[this.componentHistory.length - 1]; - Livewire.emit('componentDestroyed', id); + Livewire.emit('destroyComponent', id); } this.componentHistory.pop(); } @@ -142,26 +142,7 @@ window.LivewireUIModal = () => { this.setActiveModalComponent(id); }); - Livewire.on('destroyComponent', (name) => { - let components = this.$wire.get('components'); - let component = Object.getOwnPropertyNames(components).filter(id => { - return components[id].name === name; - }); - - let id = component[0]; - - if (id == this.activeComponent) { - this.closeModal() - Livewire.emit('componentDestroyed', id); - } else { - this.componentHistory = this.componentHistory.filter(componentId => { - return componentId !== id; - }); - - Livewire.emit('componentDestroyed', id); - } - - }); + } }; } diff --git a/src/Modal.php b/src/Modal.php index f91b3e1..95223da 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -48,7 +48,7 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->emit('activeModalComponentChanged', $id); } - public function componentDestroyed($id): void + public function destroyComponent($id): void { unset($this->components[$id]); } @@ -57,7 +57,7 @@ public function getListeners(): array { return [ 'openModal', - 'componentDestroyed' + 'destroyComponent' ]; } From b8e1ec5aac059855f19f455315e324cb92314b38 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 10:53:53 +1000 Subject: [PATCH 15/21] build --- public/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/modal.js b/public/modal.js index 27fadc0..71ee39a 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(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",n)}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.emit("componentDestroyed",this.activeComponent),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},initialize:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;t.closeModal(e,o)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)})),Livewire.on("destroyComponent",(function(e){var o=t.$wire.get("components"),n=Object.getOwnPropertyNames(o).filter((function(t){return o[t].name===e}))[0];n==t.activeComponent?(t.closeModal(),Livewire.emit("componentDestroyed",n)):(t.componentHistory=t.componentHistory.filter((function(t){return t!==n})),Livewire.emit("componentDestroyed",n))}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[a])))?o.splice(a--,1):(c=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,c,a]=o,l=0;for(i in c)n.o(c,i)&&(n.m[i]=c[i]);if(a)var u=a(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(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",n)}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.emit("destroyComponent",this.activeComponent),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},initialize:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];t.closeModal(e,o,n)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[c])))?o.splice(c--,1):(a=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,a,c]=o,l=0;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 From 0671ded56ee9e2b0914901b8f1e4c04c8bacddec Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 11:35:52 +1000 Subject: [PATCH 16/21] added tests --- src/Modal.php | 4 ++++ tests/LivewireModalComponentTest.php | 14 ++++++++---- tests/LivewireModalTest.php | 34 +++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/Modal.php b/src/Modal.php index 95223da..2c77044 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -21,6 +21,7 @@ public function resetState(): void public function openModal($component, $componentAttributes = [], $modalAttributes = []): void { + ray('open modal'); $requiredInterface = \LivewireUI\Modal\Contracts\ModalComponent::class; $componentClass = app('livewire')->getClass($component); $reflect = new ReflectionClass($componentClass); @@ -46,10 +47,13 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->activeComponent = $id; $this->emit('activeModalComponentChanged', $id); + + ray($this->components); } public function destroyComponent($id): void { + ray('destroy component'); unset($this->components[$id]); } diff --git a/tests/LivewireModalComponentTest.php b/tests/LivewireModalComponentTest.php index 4f67c29..f96b53d 100644 --- a/tests/LivewireModalComponentTest.php +++ b/tests/LivewireModalComponentTest.php @@ -11,7 +11,7 @@ public function testCloseModal(): void { Livewire::test(DemoModal::class) ->call('closeModal') - ->assertEmitted('closeModal', false, 0); + ->assertEmitted('closeModal', false, 0, false); } public function testForceCloseModal(): void @@ -19,7 +19,7 @@ public function testForceCloseModal(): void Livewire::test(DemoModal::class) ->call('forceClose') ->call('closeModal') - ->assertEmitted('closeModal', true, 0); + ->assertEmitted('closeModal', true, 0, false); } public function testModalSkipping(): void @@ -27,12 +27,18 @@ public function testModalSkipping(): void Livewire::test(DemoModal::class) ->call('skipPreviousModals', 5) ->call('closeModal') - ->assertEmitted('closeModal', false, 5); + ->assertEmitted('closeModal', false, 5, false); Livewire::test(DemoModal::class) ->call('skipPreviousModal') ->call('closeModal') - ->assertEmitted('closeModal', false, 1); + ->assertEmitted('closeModal', false, 1, false); + + Livewire::test(DemoModal::class) + ->call('skipPreviousModal') + ->call('destroySkippedModals') + ->call('closeModal') + ->assertEmitted('closeModal', false, 1, true); } public function testModalEventEmitting(): void diff --git a/tests/LivewireModalTest.php b/tests/LivewireModalTest.php index 68659b9..6e31e0d 100644 --- a/tests/LivewireModalTest.php +++ b/tests/LivewireModalTest.php @@ -7,6 +7,8 @@ use LivewireUI\Modal\Tests\Components\DemoModal; use LivewireUI\Modal\Tests\Components\InvalidModal; +use function PHPUnit\Framework\assertArrayNotHasKey; + class LivewireModalTest extends TestCase { public function testOpenModalEventListener(): void @@ -17,7 +19,7 @@ public function testOpenModalEventListener(): void // Event attributes $component = 'demo-modal'; $componentAttributes = ['message' => 'Foobar']; - $modalAttributes = ['hello' => 'world', 'closeOnEscape' => true, 'maxWidth' => '2xl', 'closeOnClickAway' => true, 'closeOnEscapeIsForceful' => true, 'dispatchCloseEvent' => false]; + $modalAttributes = ['hello' => 'world', 'closeOnEscape' => true, 'maxWidth' => '2xl', 'closeOnClickAway' => true, 'closeOnEscapeIsForceful' => true, 'dispatchCloseEvent' => false, 'destroyOnClose' => false]; // Demo modal unique identifier $id = md5($component . serialize($componentAttributes)); @@ -38,6 +40,36 @@ public function testOpenModalEventListener(): void ->assertEmitted('activeModalComponentChanged', $id); } + public function testDestroyComponentEventListener(): void + { + // Demo modal component + Livewire::component('demo-modal', DemoModal::class); + + $component = 'demo-modal'; + $componentAttributes = ['message' => 'Foobar']; + $modalAttributes = ['hello' => 'world', 'closeOnEscape' => true, 'maxWidth' => '2xl', 'closeOnClickAway' => true, 'closeOnEscapeIsForceful' => true, 'dispatchCloseEvent' => false, 'destroyOnClose' => false]; + + // Demo modal unique identifier + $id = md5($component . serialize($componentAttributes)); + + + // Demo modal unique identifier + $id = md5($component . serialize($componentAttributes)); + + Livewire::test(Modal::class) + ->emit('openModal', $component, $componentAttributes, $modalAttributes) + ->assertSet('components', [ + $id => [ + 'name' => $component, + 'attributes' => $componentAttributes, + 'modalAttributes' => $modalAttributes, + ], + ]) + ->emit('destroyComponent', $id) + ->assertSet('components', []); + + } + public function testModalReset(): void { Livewire::component('demo-modal', DemoModal::class); From 10d71c6dc0de02655de77eb6af22088379271451 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 11:38:03 +1000 Subject: [PATCH 17/21] removed ray --- src/Modal.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Modal.php b/src/Modal.php index 2c77044..95223da 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -21,7 +21,6 @@ public function resetState(): void public function openModal($component, $componentAttributes = [], $modalAttributes = []): void { - ray('open modal'); $requiredInterface = \LivewireUI\Modal\Contracts\ModalComponent::class; $componentClass = app('livewire')->getClass($component); $reflect = new ReflectionClass($componentClass); @@ -47,13 +46,10 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->activeComponent = $id; $this->emit('activeModalComponentChanged', $id); - - ray($this->components); } public function destroyComponent($id): void { - ray('destroy component'); unset($this->components[$id]); } From a3add60ac74af1b3f3cd2659b3efc4fbc64a5850 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 11:48:45 +1000 Subject: [PATCH 18/21] updated readme --- README.md | 16 ++++++++++++++++ src/Modal.php | 4 ---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0fc8cc2..d628793 100644 --- a/README.md +++ b/README.md @@ -269,6 +269,14 @@ By default, the modal will close when you click outside the modal. If you want t } ``` + By default, when a child modal is closed, the closed components state is still available if the same modal component is opened again. If you would like to destroy the component when its closed you can override the static `destroyOnClose` method and have it return `true`. When a destroyed modal is opened again its state will be reset. + ```php + public static function destroyOnClose(): bool + { + return true; + } + ``` + ## Skipping previous modals In some cases you might want to skip previous modals. For example: 1. Team overview modal @@ -313,6 +321,12 @@ class DeleteTeam extends ModalComponent } ``` +You can also optionally call the `destroySkippedModals()` method to destroy the skipped modals so if any are opened again their state will be reset + + + + + ## Building Tailwind CSS for production To purge the classes used by the package, add the following lines to your purge array in `tailwind.config.js`: ```js @@ -405,6 +419,8 @@ return [ 'close_modal_on_escape_is_forceful' => true, 'dispatch_close_event' => false, + + 'destroy_on_close' => false, ], ]; ``` diff --git a/src/Modal.php b/src/Modal.php index 69c6183..0a6b561 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -21,7 +21,6 @@ public function resetState(): void public function openModal($component, $componentAttributes = [], $modalAttributes = []): void { - ray('open modal'); $requiredInterface = \LivewireUI\Modal\Contracts\ModalComponent::class; $componentClass = app('livewire')->getClass($component); $reflect = new ReflectionClass($componentClass); @@ -47,13 +46,10 @@ public function openModal($component, $componentAttributes = [], $modalAttribute $this->activeComponent = $id; $this->emit('activeModalComponentChanged', $id); - - ray($this->components); } public function destroyComponent($id): void { - ray('destroy component'); unset($this->components[$id]); } From 47ffaedc950ae9981d0e6f711beb8d38ad0c0380 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Tue, 31 Aug 2021 11:58:05 +1000 Subject: [PATCH 19/21] removed duplicate call --- src/Modal.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Modal.php b/src/Modal.php index 0a6b561..95223da 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -53,11 +53,6 @@ public function destroyComponent($id): void unset($this->components[$id]); } - public function destroyComponent($id): void - { - unset($this->components[$id]); - } - public function getListeners(): array { return [ From b144856fdb2bf4cbdebb0c75d6b3d50e00a84394 Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Fri, 3 Sep 2021 08:03:26 +1000 Subject: [PATCH 20/21] removed duplicate line in test --- tests/LivewireModalTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/LivewireModalTest.php b/tests/LivewireModalTest.php index 6e31e0d..d55ab46 100644 --- a/tests/LivewireModalTest.php +++ b/tests/LivewireModalTest.php @@ -49,10 +49,6 @@ public function testDestroyComponentEventListener(): void $componentAttributes = ['message' => 'Foobar']; $modalAttributes = ['hello' => 'world', 'closeOnEscape' => true, 'maxWidth' => '2xl', 'closeOnClickAway' => true, 'closeOnEscapeIsForceful' => true, 'dispatchCloseEvent' => false, 'destroyOnClose' => false]; - // Demo modal unique identifier - $id = md5($component . serialize($componentAttributes)); - - // Demo modal unique identifier $id = md5($component . serialize($componentAttributes)); From 755349f3cca00f85359066b3d7bfc822fe4b6c2c Mon Sep 17 00:00:00 2001 From: thermiteplasma Date: Fri, 3 Sep 2021 08:05:31 +1000 Subject: [PATCH 21/21] changed back to init --- public/modal.js | 2 +- resources/js/modal.js | 2 +- resources/views/modal.blade.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/public/modal.js b/public/modal.js index 71ee39a..9a711b4 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(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",n)}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.emit("destroyComponent",this.activeComponent),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},initialize:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];t.closeModal(e,o,n)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[c])))?o.splice(c--,1):(a=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,a,c]=o,l=0;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(!0===this.getActiveComponentModalAttribute("dispatchCloseEvent")){var n=this.$wire.get("components")[this.activeComponent].name;Livewire.emit("modalClosed",n)}if(!0===this.getActiveComponentModalAttribute("destroyOnClose")&&Livewire.emit("destroyComponent",this.activeComponent),e>0)for(var i=0;i1&&void 0!==arguments[1]&&arguments[1];if(this.show=!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="sm:max-w-"+this.getActiveComponentModalAttribute("maxWidth")):(this.showActiveComponent=!1,n=400,setTimeout((function(){e.activeComponent=t,e.showActiveComponent=!0,e.modalWidth="sm:max-w-"+e.getActiveComponentModalAttribute("maxWidth")}),300)),this.$nextTick((function(){var o=e.$refs[t].querySelector("[autofocus]");o&&setTimeout((function(){o.focus()}),n)}))}},focusables:function(){return t(this.$el.querySelectorAll("a, button, input, 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},init:function(){var t=this;this.$watch("show",(function(e){e?document.body.classList.add("overflow-y-hidden"):(document.body.classList.remove("overflow-y-hidden"),setTimeout((function(){t.activeComponent=!1,t.$wire.resetState()}),300))})),Livewire.on("closeModal",(function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];t.closeModal(e,o,n)})),Livewire.on("activeModalComponentChanged",(function(e){t.setActiveModalComponent(e)}))}}}},754:()=>{}},o={};function n(t){var i=o[t];if(void 0!==i)return i.exports;var r=o[t]={exports:{}};return e[t](r,r.exports,n),r.exports}n.m=e,t=[],n.O=(e,o,i,r)=>{if(!o){var s=1/0;for(l=0;l=r)&&Object.keys(n.O).every((t=>n.O[t](o[c])))?o.splice(c--,1):(a=!1,r0&&t[l-1][2]>r;l--)t[l]=t[l-1];t[l]=[o,i,r]},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,r,[s,a,c]=o,l=0;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.js b/resources/js/modal.js index bfebb5d..7bda255 100644 --- a/resources/js/modal.js +++ b/resources/js/modal.js @@ -120,7 +120,7 @@ window.LivewireUIModal = () => { prevFocusableIndex() { return Math.max(0, this.focusables().indexOf(document.activeElement)) - 1 }, - initialize() { + init() { this.$watch('show', value => { if (value) { document.body.classList.add('overflow-y-hidden'); diff --git a/resources/views/modal.blade.php b/resources/views/modal.blade.php index 9c26396..6d2dbee 100644 --- a/resources/views/modal.blade.php +++ b/resources/views/modal.blade.php @@ -8,7 +8,7 @@