Skip to content

Commit c00f080

Browse files
committed
stack modal system
1 parent 7a047b4 commit c00f080

File tree

7 files changed

+50
-61
lines changed

7 files changed

+50
-61
lines changed

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
blank_issues_enabled: false
22
contact_links:
33
- name: Ask a question
4-
url: https://github.com/elegantengineeringtech/livewire-modal/discussions/new?category=q-a
4+
url: https://github.com/ElegantEngineeringTech/livewire-modal/discussions/new?category=q-a
55
about: Ask the community for help
66
- name: Request a feature
7-
url: https://github.com/elegantengineeringtech/livewire-modal/discussions/new?category=ideas
7+
url: https://github.com/ElegantEngineeringTech/livewire-modal/discussions/new?category=ideas
88
about: Share ideas for new features
99
- name: Report a security issue
10-
url: https://github.com/elegantengineeringtech/livewire-modal/security/policy
10+
url: https://github.com/ElegantEngineeringTech/livewire-modal/security/policy
1111
about: Learn how to notify us for sensitive bugs

resources/views/components/slideover.blade.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
<x-livewire-modal::modal :attributes="$attributes->class([
66
'h-full',
77
match ($position) {
8-
'center' => 'mx-6',
9-
'right' => 'mr-6',
10-
'left' => 'ml-6',
8+
'center' => 'sm:mx-6',
9+
'right' => 'sm:mr-6',
10+
'left' => 'sm:ml-6',
1111
default => '',
1212
},
1313
])" :position="$position">

resources/views/livewire/modal.blade.php

Lines changed: 33 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,30 @@
11
<div x-data="{
22
modalOpen: $wire.entangle('open', false),
33
components: $wire.entangle('components', false), // Array of loaded components
4-
stack: [], // Array or component Ids to display
4+
modalHistory: [], // Array or component Ids to display
55
get modalActiveId() {
6-
if (this.stack.length) {
7-
return this.stack[this.stack.length - 1];
8-
}
9-
10-
return null;
6+
return this.modalHistory.length ? this.modalHistory[this.modalHistory.length - 1] : null;
117
},
128
get activeComponent() {
139
return this.components.find((item) => item.id === this.modalActiveId);
1410
},
11+
get activeStack() {
12+
return this.activeComponent?.stack ?? null;
13+
},
1514
get lastComponent() {
16-
if (this.components.length) {
17-
return this.components[this.components.length - 1];
18-
}
19-
return null;
15+
return this.components.length ? this.components[this.components.length - 1] : null;
2016
},
2117
areComponentsEqual({ component: component1, props: props1, params: params1 }, { component: component2, props: props2, params: params2 }) {
2218
return component1 === component2 &&
2319
JSON.stringify(props1) === JSON.stringify(props2) &&
2420
JSON.stringify(params1) === JSON.stringify(params2);
2521
},
26-
findStackIndex(id, reverse = false) {
22+
findHistoryIndex(id, reverse = false) {
2723
if (reverse) {
28-
return this.stack.length - 1 - this.findStackIndex(id);
24+
return this.modalHistory.length - 1 - this.findHistoryIndex(id);
2925
}
3026
31-
return this.stack.findIndex((item) => id === item);
27+
return this.modalHistory.findIndex((item) => id === item);
3228
},
3329
sync() {
3430
this.$wire.$refresh();
@@ -37,14 +33,11 @@
3733
return Math.random().toString(36).substring(2, 7);
3834
},
3935
makeComponentFromEvent(event) {
40-
const component = event.detail?.component ?? null;
41-
const props = event.detail?.props ?? [];
42-
const params = event.detail?.params ?? [];
43-
4436
return {
45-
component: component,
46-
props: props,
47-
params: params,
37+
component: event.detail?.component ?? null,
38+
props: event.detail?.props ?? [],
39+
params: event.detail?.params ?? [],
40+
stack: event.detail?.stack ?? this.$wire.stack,
4841
};
4942
},
5043
getPreloadedComponent(eventComponent) {
@@ -77,35 +70,34 @@
7770
},
7871
openNewComponent(eventComponent) {
7972
eventComponent.id = this.generateRandomId();
73+
8074
this.components.push(eventComponent);
81-
this.stack.push(eventComponent.id);
75+
this.modalHistory.push(eventComponent.id);
8276
8377
this.modalOpen = true;
8478
this.sync();
8579
},
8680
openPreloadedComponent(component) {
8781
component.preloaded = false;
8882
89-
this.stack.push(component.id);
83+
this.modalHistory.push(component.id);
9084
this.modalOpen = true;
9185
},
9286
onOpen(event) {
9387
const eventComponent = this.makeComponentFromEvent(event);
94-
9588
const preloadedComponent = this.getPreloadedComponent(eventComponent);
9689
9790
if (preloadedComponent) {
9891
this.openPreloadedComponent(preloadedComponent);
9992
} else {
10093
this.openNewComponent(eventComponent);
10194
}
102-
10395
},
10496
findComponentById(id) {
10597
return this.components.find((item) => item.id === id);
10698
},
10799
removeComponentById(id) {
108-
this.stack = this.stack.filter((item) => item !== id);
100+
this.modalHistory = this.modalHistory.filter((item) => item !== id);
109101
this.components = this.components.filter((item) => item.id !== id);
110102
},
111103
removeComponent(eventComponent) {
@@ -114,9 +106,7 @@
114106
.forEach((item) => this.removeComponentById(item.id));
115107
},
116108
removeActiveComponent() {
117-
if (this.modalActiveId) {
118-
this.removeComponentById(this.modalActiveId);
119-
}
109+
this.modalActiveId && this.removeComponentById(this.modalActiveId);
120110
},
121111
onClose(event) {
122112
const eventComponent = this.makeComponentFromEvent(event);
@@ -127,14 +117,12 @@
127117
this.removeActiveComponent();
128118
}
129119
130-
if (this.stack.length < 1) {
131-
this.modalOpen = false;
132-
}
120+
this.modalOpen = this.modalHistory.length > 0;
133121
134122
this.sync();
135123
},
136124
onCloseAll() {
137-
this.stack = [];
125+
this.modalHistory = [];
138126
this.components = [];
139127
this.modalOpen = false;
140128
this.sync();
@@ -173,22 +161,21 @@ class="fixed left-0 top-0 z-40 grid h-dvh w-full select-none overflow-hidden bg-
173161
get modalId() {
174162
return '{{ $id }}';
175163
},
176-
get modalMode() {
177-
const activeMode = activeComponent?.params.mode ?? null;
178-
const componentMode = findComponentById(this.modalId)?.params.mode ?? null;
179-
180-
if (activeComponent && activeMode === null) {
181-
return null;
182-
}
164+
get isModalActive() {
165+
return modalActiveId === this.modalId;
166+
},
167+
get isModalStacked() {
168+
const component = findComponentById(this.modalId);
169+
const componentStack = component?.stack ?? null;
183170
184-
return componentMode;
171+
return activeStack && activeStack === componentStack;
185172
},
186173
get modalIndexReversed() {
187-
return findStackIndex(this.modalId, true);
174+
return findHistoryIndex(this.modalId, true);
188175
},
189176
modalWrapper: {
190177
['x-bind:class']() {
191-
if (this.modalMode === 'stack') {
178+
if (this.isModalStacked) {
192179
return 'relative flex size-full pointer-events-none [&>*]:pointer-events-auto';
193180
}
194181
return 'contents';
@@ -197,13 +184,13 @@ class="fixed left-0 top-0 z-40 grid h-dvh w-full select-none overflow-hidden bg-
197184
return `grid-area: stack;`;
198185
},
199186
['x-bind:inert']() {
200-
return modalActiveId !== this.modalId;
187+
return !this.isModalActive;
201188
},
202189
['x-show']() {
203-
if (this.modalMode === 'stack') {
204-
return stack.includes(this.modalId);
190+
if (this.isModalStacked) {
191+
return modalHistory.includes(this.modalId);
205192
}
206-
return modalActiveId === this.modalId;
193+
return this.isModalActive;
207194
},
208195
},
209196
}" x-bind="modalWrapper" class="select-text"

src/Livewire/Modal.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
namespace Elegantly\LivewireModal\Livewire;
66

7+
use Livewire\Attributes\Locked;
78
use Livewire\Component;
89

910
class Modal extends Component
1011
{
11-
public ?string $mode = null;
12+
#[Locked]
13+
public ?string $stack = null;
1214

1315
public bool $open = false;
1416

workbench/resources/views/demo.blade.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
<div class="flex grow items-center justify-center border-b">
7272

7373
<button type="button" class="rounded-md border px-3.5 py-1.5 shadow-sm focus:ring active:shadow-none"
74-
x-modal:open="{ component: 'card', params:{ mode: 'stack' } }">
74+
x-modal:open="{ component: 'card', stack: 'card' }">
7575
Open Stacked Modal
7676
</button>
7777

@@ -107,12 +107,12 @@
107107
<div class="flex grow flex-wrap items-center justify-center gap-2 border-b">
108108

109109
<button type="button" class="rounded-md border px-3.5 py-1.5 shadow-sm focus:ring active:shadow-none"
110-
x-modal:open="{ component: 'slideover', params:{ mode: 'stack' } }">
110+
x-modal:open="{ component: 'slideover', stack: 'slideover'}">
111111
Open Stacked Slideover
112112
</button>
113113

114114
<button type="button" class="rounded-md border px-3.5 py-1.5 shadow-sm focus:ring active:shadow-none"
115-
x-modal:open="{ component: 'slideover', props:{ position: 'left' }, params:{ mode: 'stack' } }">
115+
x-modal:open="{ component: 'slideover', props:{ position: 'left' }, stack: 'slideover-left' }">
116116
Open Left
117117
</button>
118118

workbench/resources/views/livewire/card.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
</button>
2121

2222
<button type="button" class="rounded-md border px-3.5 py-1.5 shadow-sm focus:ring active:shadow-none"
23-
x-modal:open="{ component: 'card', params:{ mode: 'stack' } }">
23+
x-modal:open="{ component: 'card', stack: 'card' }">
2424
Open Stacked Modal
2525
</button>
2626

2727
<button type="button" class="rounded-md border px-3.5 py-1.5 shadow-sm focus:ring active:shadow-none"
28-
x-modal:open="{ component: 'slideover', params:{ mode: 'stack' } }">
28+
x-modal:open="{ component: 'slideover', stack: 'slideover' }">
2929
Open Stacked Slideover
3030
</button>
3131
</div>

workbench/resources/views/livewire/slideover.blade.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@
2121
</button>
2222

2323
<button type="button" class="rounded-md border px-3.5 py-1.5 shadow-sm focus:ring active:shadow-none"
24-
x-modal:open="{ component: 'card', params:{ mode: 'stack' } }">
24+
x-modal:open="{ component: 'card', stack: 'card' }">
2525
Open Stacked Modal
2626
</button>
2727

2828
<button type="button" class="rounded-md border px-3.5 py-1.5 shadow-sm focus:ring active:shadow-none"
29-
x-modal:open="{ component: 'slideover', params:{ mode: 'stack' } }">
29+
x-modal:open="{ component: 'slideover', stack: 'slideover' }">
3030
Open Stacked Slideover
3131
</button>
3232

3333
<button type="button" class="rounded-md border px-3.5 py-1.5 shadow-sm focus:ring active:shadow-none"
34-
x-modal:open="{ component: 'slideover', props:{ position: 'left' }, params:{ mode: 'stack' } }">
34+
x-modal:open="{ component: 'slideover', props:{ position: 'left' }, stack: 'slideover-left' }">
3535
Open Stacked Slideover Left
3636
</button>
3737
</div>

0 commit comments

Comments
 (0)