-
Notifications
You must be signed in to change notification settings - Fork 223
/
loading-states.blade.php
executable file
·167 lines (125 loc) · 5.67 KB
/
loading-states.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
* [Introduction](#introduction)
* [Toggling elements during "loading" states](#toggling-elements)
* [Delaying loading indicator](#delaying-loading)
* [Targeting specific actions](#targeting-actions)
* [Targeting models](#targeting-models)
* [Toggling classes](#toggling-classes)
* [Toggling attributes](#toggling-attributes)
## Introduction {#introduction}
Because Livewire makes a roundtrip to the server every time an action is triggered on the page, there are cases when the page may not react immediately to a user event (like a click). Livewire allows you to easily display loading states, which can make your app feel more responsive.
## Toggling elements during "loading" states {#toggling-elements}
Elements with the `wire:loading` directive are only visible while waiting for actions to complete (network requests).
@component('components.code', ['lang' => 'blade'])
<div>
<button wire:click="checkout">Checkout</button>
<div wire:loading>
Processing Payment...
</div>
</div>
@endcomponent
When the "Checkout" button is clicked, the "Processing Payment..." message will show. When the action is finished, the message will disappear.
By default, Livewire set's a loading element's "display" CSS property to "inline-block". If you want Livewire to use "flex" or "grid", you can use the following modifiers.
@component('components.code', ['lang' => 'blade'])
<div wire:loading.block>...</div>
<div wire:loading.flex>...</div>
<div wire:loading.inline-flex>...</div>
<div wire:loading.grid>...</div>
<div wire:loading.inline>...</div>
<div wire:loading.table>...</div>
@endcomponent
You can also "hide" an element during a loading state using the `.remove` modifier.
@component('components.code', ['lang' => 'blade'])
<div>
<button wire:click="checkout">Checkout</button>
<div wire:loading.remove>
Hide Me While Loading...
</div>
</div>
@endcomponent
## Delaying loading indicator {#delaying-loading}
If you want to avoid flickering because loading is very fast, you can add the `.delay` modifier, and it will only show up if loading takes longer than `200ms`.
@component('components.code', ['lang' => 'blade'])
<div wire:loading.delay>...</div>
@endcomponent
If you wish, you can customize the delay duration with the following modifiers:
@component('components.code', ['lang' => 'blade'])
<div wire:loading.delay.shortest>...</div> <!-- 50ms -->
<div wire:loading.delay.shorter>...</div> <!-- 100ms -->
<div wire:loading.delay.short>...</div> <!-- 150ms -->
<div wire:loading.delay>...</div> <!-- 200ms -->
<div wire:loading.delay.long>...</div> <!-- 300ms -->
<div wire:loading.delay.longer>...</div> <!-- 500ms -->
<div wire:loading.delay.longest>...</div> <!-- 1000ms -->
@endcomponent
## Targeting specific actions {#targeting-actions}
The method outlined above works well for simple components. For more complex components, you may want to show loading indicators only for specific actions.
@component('components.code', ['lang' => 'blade'])
<div>
<button wire:click="checkout">Checkout</button>
<button wire:click="cancel">Cancel</button>
<div wire:loading wire:target="checkout">
Processing Payment...
</div>
</div>
@endcomponent
In the above example, the loading indicator will be displayed when the "Checkout" button is clicked, but not when the "Cancel" button is clicked.
`wire:target` can accept multiple arguments in a comma separated format like this: `wire:target="foo, bar"`.
You may also target actions with specific parameters.
@component('components.code', ['lang' => 'blade'])
<div>
<button wire:click="update('bob')">Update</button>
<div wire:loading wire:target="update('bob')">
Updating Bob...
</div>
</div>
@endcomponent
If you wish to trigger a loading indicator when ANY of the properties of an array change, you can simply target the entire array:
@component('components.code', ['lang' => 'blade'])
<div>
<input type="text" wire:model="post.title">
<input type="text" wire:model="post.author">
<input type="text" wire:model="post.content">
<div wire:loading wire:target="post">
Updating Post...
</div>
</div>
@endcomponent
## Targeting models {#targeting-models}
In addition to actions, you can also target whenever a `wire:model` is synchronized.
@component('components.code', ['lang' => 'blade'])
<div>
<input wire:model="quantity">
<div wire:loading wire:target="quantity">
Updating quantity...
</div>
</div>
@endcomponent
## Toggling classes {#toggling-classes}
You can add or remove classes from an element during loading states, by adding the `.class` modifier to the `wire:loading` directive.
@component('components.code', ['lang' => 'blade'])
<div>
<button wire:click="checkout" wire:loading.class="bg-gray">
Checkout
</button>
</div>
@endcomponent
Now, when the "Checkout" button is clicked, the background will turn gray while the network request is processing.
You can also perform the inverse and remove classes by adding the `.remove` modifier.
@component('components.code', ['lang' => 'blade'])
<div>
<button wire:click="checkout" wire:loading.class.remove="bg-blue" class="bg-blue">
Checkout
</button>
</div>
@endcomponent
Now the `bg-blue` class will be removed from the button while loading.
## Toggling attributes {#toggling-attributes}
Similar to classes, HTML attributes can be added or removed from elements during loading states:
@component('components.code', ['lang' => 'blade'])
<div>
<button wire:click="checkout" wire:loading.attr="disabled">
Checkout
</button>
</div>
@endcomponent
Now, when the "Checkout" button is clicked, the `disabled="true"` attribute will be added to the element while loading.