Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4cf83a5
added remove from stack
omusovski Aug 25, 2021
811df70
rename init to initialize for alpinejs 2 and 3 compat
thermiteplasma Aug 30, 2021
a591aaf
support for destroyComponent, destroy on close and destroySkipped
thermiteplasma Aug 30, 2021
59e33c4
build production
thermiteplasma Aug 30, 2021
a2dbff1
updated closeModal parameters
thermiteplasma Aug 30, 2021
2336e92
removed destroyComponent alpine listeners
thermiteplasma Aug 31, 2021
c596b52
build
thermiteplasma Aug 31, 2021
fe7d68d
added tests
thermiteplasma Aug 31, 2021
23038d7
added remove from stack
omusovski Aug 25, 2021
5f8d0c3
rename init to initialize for alpinejs 2 and 3 compat
thermiteplasma Aug 30, 2021
812ce81
support for destroyComponent, destroy on close and destroySkipped
thermiteplasma Aug 30, 2021
360d758
build production
thermiteplasma Aug 30, 2021
d589721
updated closeModal parameters
thermiteplasma Aug 30, 2021
50c541e
removed destroyComponent alpine listeners
thermiteplasma Aug 31, 2021
b8e1ec5
build
thermiteplasma Aug 31, 2021
0671ded
added tests
thermiteplasma Aug 31, 2021
10d71c6
removed ray
thermiteplasma Aug 31, 2021
1ed4052
Merge branch 'removeFromStack' of github.com:olivermusovski/modal int…
thermiteplasma Aug 31, 2021
a3add60
updated readme
thermiteplasma Aug 31, 2021
47ffaed
removed duplicate call
thermiteplasma Aug 31, 2021
b144856
removed duplicate line in test
thermiteplasma Sep 2, 2021
755349f
changed back to init
thermiteplasma Sep 2, 2021
c02e9e5
Merge branch 'livewire-ui:main' into removeFromStack
thermiteplasma Oct 26, 2021
edb548a
Merge branch 'main' into removeFromStack
PhiloNL Nov 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,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
Expand Down Expand Up @@ -314,6 +322,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
Expand Down Expand Up @@ -406,6 +420,8 @@ return [
'close_modal_on_escape_is_forceful' => true,

'dispatch_close_event' => false,

'destroy_on_close' => false,
],
];
```
Expand Down
2 changes: 2 additions & 0 deletions config/livewire-ui-modal.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,7 @@
'close_modal_on_escape_is_forceful' => true,

'dispatch_close_event' => false,

'destroy_on_close' => false,
],
];
2 changes: 1 addition & 1 deletion public/modal.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions resources/js/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('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('destroyComponent', id);
}
this.componentHistory.pop();
}
}
Expand Down Expand Up @@ -126,13 +134,15 @@ 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) => {
this.setActiveModalComponent(id);
});


}
};
}
2 changes: 1 addition & 1 deletion resources/views/modal.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
<div x-show.immediate="activeComponent == '{{ $id }}'" x-ref="{{ $id }}">
<div x-show.immediate="activeComponent == '{{ $id }}'" x-ref="{{ $id }}" wire:key="{{ $id }}">
@livewire($component['name'], $component['attributes'], key($id))
</div>
@empty
Expand Down
7 changes: 7 additions & 0 deletions src/Modal.php
Original file line number Diff line number Diff line change
Expand Up @@ -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),
];
Expand All @@ -47,10 +48,16 @@ public function openModal($component, $componentAttributes = [], $modalAttribute
$this->emit('activeModalComponentChanged', $id);
}

public function destroyComponent($id): void
{
unset($this->components[$id]);
}

public function getListeners(): array
{
return [
'openModal',
'destroyComponent'
];
}

Expand Down
23 changes: 19 additions & 4 deletions src/ModalComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,26 @@ abstract class ModalComponent extends Component implements Contract

public int $skipModals = 0;

public function skipPreviousModals($count = 1): self
public bool $destroySkipped = false;

public function destroySkippedModals(): self
{
$this->destroySkipped = true;

return $this;
}

public function skipPreviousModals($count = 1, $destroy = false): self
{
$this->skipPreviousModal($count);
$this->skipPreviousModal($count, $destroy);

return $this;
}

public function skipPreviousModal($count = 1): self
public function skipPreviousModal($count = 1, $destroy = false): self
{
$this->skipModals = $count;
$this->destroySkipped = $destroy;

return $this;
}
Expand All @@ -34,7 +44,7 @@ public function forceClose(): self

public function closeModal(): void
{
$this->emit('closeModal', $this->forceClose, $this->skipModals);
$this->emit('closeModal', $this->forceClose, $this->skipModals, $this->destroySkipped);
}

public function closeModalWithEvents(array $events): void
Expand Down Expand Up @@ -68,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) {
Expand Down
14 changes: 10 additions & 4 deletions tests/LivewireModalComponentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,34 @@ public function testCloseModal(): void
{
Livewire::test(DemoModal::class)
->call('closeModal')
->assertEmitted('closeModal', false, 0);
->assertEmitted('closeModal', false, 0, false);
}

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
{
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
Expand Down
30 changes: 29 additions & 1 deletion tests/LivewireModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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));
Expand All @@ -38,6 +40,32 @@ 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));

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);
Expand Down