Skip to content
This repository was archived by the owner on Jan 27, 2025. It is now read-only.

Commit 7ecf683

Browse files
Merge pull request #32 from marcorieser/livewire-3
Compatibility for Livewire 3
2 parents 8213345 + 8eb9b17 commit 7ecf683

File tree

4 files changed

+103
-108
lines changed

4 files changed

+103
-108
lines changed

README.md

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Statamic Livewire
22
<!-- statamic:hide -->
3-
![Statamic 3.0+](https://img.shields.io/badge/Statamic-3.0+-FF269E?style=for-the-badge&link=https://statamic.com)
3+
![Statamic 4.0+](https://img.shields.io/badge/Statamic-4.0+-FF269E?style=for-the-badge&link=https://statamic.com)
44
[![Latest Version on Packagist](https://img.shields.io/packagist/v/jonassiewertsen/statamic-livewire.svg?style=for-the-badge)](https://packagist.org/packages/jonassiewertsen/statamic-livewire)
55
<!-- /statamic:hide -->
66

@@ -21,34 +21,38 @@ composer require jonassiewertsen/statamic-livewire
2121
```
2222

2323
## General documentation
24-
[Laravel Livewire Docs](https://laravel-livewire.com/docs/quickstart)
24+
[Livewire Docs](https://livewire.laravel.com/docs/quickstart)
2525

26-
## Setup inside your template
26+
## Livewire scripts and styles
2727

28-
Include the Livewire styles and scripts __on every page__ that will be using Livewire:
28+
Livewire injects its styles and scripts automatically into the page. However, if you want to include them [manually](https://livewire.laravel.com/docs/installation#manually-including-livewires-frontend-assets), you can do so by using the respective tags `{{ livewire:styles }}` and`{{ livewire:scripts }}`.
2929

30-
```html
31-
...
32-
<!-- If using Antlers -->
33-
{{ livewire:styles }}
30+
In case you need to include some custom Alpine plugins, you can [bundle the assets yourself](https://livewire.laravel.com/docs/installation#manually-bundling-livewire-and-alpine) and disable the automatic injection by using the `{{ livewire:scriptConfig }}` tag. Do not forget to include the `{{ livewire:styles }}` tag as well.
3431

35-
<!-- If using Blade -->
36-
@livewireStyles
37-
</head>
38-
<body>
39-
40-
...
41-
<!-- If using Antlers -->
42-
{{ livewire:scripts }}
43-
44-
<!-- Blade -->
45-
@livewireScripts
46-
</body>
32+
```html
33+
<html>
34+
<head>
35+
<!-- If using Antlers -->
36+
{{ livewire:styles }}
37+
38+
<!-- If using Blade -->
39+
@livewireStyles
40+
</head>
41+
<body>
42+
43+
...
44+
<!-- If using Antlers -->
45+
{{ livewire:scripts }} / {{ livewire:scriptsConfig }}
46+
47+
<!-- Blade -->
48+
@livewireScripts / @livewireScriptConfig
49+
</body>
4750
</html>
4851
```
4952

5053
### Include components
51-
You can create Livewire components as described in the general documentation. To include your Livewire component:
54+
You can create Livewire components as described in the [general documentation](https://livewire.laravel.com/docs/components).
55+
To include your Livewire component:
5256
```html
5357
<body>
5458
<!-- If using Antlers -->
@@ -62,7 +66,7 @@ You can create Livewire components as described in the general documentation. To
6266
### Blade or Antlers? Both!
6367
If creating a Livewire component, you need to render a template file
6468

65-
```
69+
```php
6670
namespace App\Http\Livewire;
6771

6872
use Livewire\Component;
@@ -75,10 +79,10 @@ class Counter extends Component
7579
}
7680
}
7781
```
78-
More Information: (https://laravel-livewire.com/docs/quickstart#create-a-component)
82+
More Information: (https://livewire.laravel.com/docs/components)
7983

8084
Normally your template file would be a blade file, named `counter.blade.php`. Great, but what about Antlers?
81-
Rename your template to `counter.antlers.html`, use Antlers syntax and do wathever you like. **No need to change** anything inside your component Controller. How cool is that?
85+
Rename your template to `counter.antlers.html`, use Antlers syntax and do whatever you like. **No need to change** anything inside your component Controller. How cool is that?
8286

8387
### Passing Initial Parameters
8488
You can pass data into a component by passing additional parameters
@@ -110,13 +114,13 @@ class ShowContact extends Component
110114
}
111115
```
112116

113-
The [Official Livewire documentation](https://laravel-livewire.com/docs/rendering-components)
117+
The [Official Livewire documentation](https://livewire.laravel.com/docs/components#rendering-components)
114118

115119
### Paginating Data
116120
You can paginate results by using the WithPagination trait.
117121

118122
#### Blade
119-
To use pagination with Blade, please use the `Livewire\WithPagination` namespace for your trait as described in the [Livewire docs](https://laravel-livewire.com/docs/2.x/pagination#paginating-data).
123+
To use pagination with Blade, please use the `Livewire\WithPagination` namespace for your trait as described in the [Livewire docs](https://livewire.laravel.com/docs/pagination#basic-usage).
120124

121125
### Antlers
122126
Pagination with Antlers does work similar. Make sure to use the `Jonassiewertsen\Livewire\WithPagination` namespace for your trait if working with Antlers.
@@ -154,46 +158,68 @@ class ShowArticles extends Component
154158
```
155159

156160
### Entangle: Sharing State Between Livewire And Alpine
157-
In case you want to share state between Livewire and Alpine, there is a Blade directive called @entangle:\
158-
[Livewire docs](https://laravel-livewire.com/docs/2.x/alpine-js#:~:text=Livewire%20has%20an%20incredibly%20powerful,other%20will%20also%20be%20changed.)
159-
160-
To be usable with Antlers, we do provide an dedicated Tag:
161+
In case you want to share state between Livewire and Alpine, there is a Blade directive called `@entangle`. To be usable with Antlers, we do provide a dedicated tag:
161162
```html
162163
<!-- With Antlers -->
163-
<div x-data="{ open: {{ livewire:entangle property='showDropdown' }} }">
164+
<div x-data="{ open: {{ livewire:entangle property='showDropdown' modifier='live' }} }">
164165

165166
<!-- With Blade -->
166-
<div x-data="{ open: @entangle('showDropdown').defer }">
167+
<div x-data="{ open: @entangle('showDropdown').live }">
167168
```
168169

170+
It's worth mentioning that, since Livewire v3 now builds on top of Alpine, the `@entangle` directive is not documented anymore. Instead, it's possible to entangle the data via [the `$wire` object](https://livewire.laravel.com/docs/javascript#the-wire-object).
171+
```html
172+
<div x-data="{ open: $wire.entangle('showDropdown', true) }">
173+
```
169174
### This: Accessing the Livewire component
170175
You can access and perform actions on the Livewire component like this:
171176

172177
```html
173-
<!-- With Antlers -->
174-
{{ livewire:this set="('name', 'Jack')" }}
178+
<script>
179+
document.addEventListener('livewire:initialized', function () {
180+
// With Antlers
181+
{{ livewire:this set="('name', 'Jack')" }}
182+
183+
// With Blade
184+
@this.set('name', 'Jack')
185+
})
186+
</script>
187+
```
188+
It's worth mentioning that, since Livewire v3 now builds on top of Alpine, the `@this` directive is not used widely anymore. Instead, it's possible to [access and manipulate the state directly via JavaScript](https://livewire.laravel.com/docs/properties#accessing-properties-from-javascript) / [the `$wire` object](https://livewire.laravel.com/docs/javascript#the-wire-object).
189+
```html
190+
<script>
191+
document.addEventListener('livewire:initialized', function () {
192+
// `{{ livewire:this }}` returns the instance of the current component
193+
{{ livewire:this }}.set('name', 'Jack')
194+
})
195+
</script>
196+
```
197+
### Lazy Components
198+
Livewire allows you to [lazy load components](https://livewire.laravel.com/docs/lazy) that would otherwise slow down the initial page load. For this you can simply pass `lazy="true"` as argument to your component tag.
175199

176-
<!-- With Blade -->
177-
@this.set('name', 'Jack')
200+
```html
201+
<!-- With Antlers -->
202+
{{ livewire:your-component-name :contact="contact" lazy="true" }}
178203
```
179204

180205
## Other Statamic Livewire Packages
181206
If using Livewire, those packages might be interesting for you as well:
182207
- [Statamic live search](https://github.com/jonassiewertsen/statamic-live-search)
183208
- [Statamic Livewire Forms](https://github.com/aerni/statamic-livewire-forms)
209+
- [Antlers Components](https://github.com/Stillat/antlers-components)
184210

185-
Did I miss a link? let me know!
211+
Did I miss a link? Let me know!
186212

187213
## Credits
188214

189-
Thanks to:\
215+
Thanks to:
190216
- [Caleb](https://github.com/calebporzio) and the community for building [Livewire](https://laravel-livewire.com/)
191217
- [Austenc](https://github.com/austenc) for the Statamic marketplace preview image
192218

193219
## Requirements
194-
- PHP 7.4 or 8.0
195-
- Laravel 7, 8, 9 or 10
196-
- Statamic 3 or 4
220+
- PHP 8.1
221+
- Laravel 10
222+
- Statamic 4
197223

198224
# Support
199225
I love to share with the community. Nevertheless, it does take a lot of work, time and effort.
@@ -202,4 +228,3 @@ I love to share with the community. Nevertheless, it does take a lot of work, ti
202228

203229
# License
204230
This plugin is published under the MIT license. Feel free to use it and remember to spread love.
205-

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
"email": "[email protected]"
2424
},
2525
"require": {
26-
"php": "^7.4 || ^8.0",
27-
"illuminate/support": "^7.0 || ^8.0 || ^9.0 || ^10.0",
28-
"statamic/cms": "3.0.* || 3.1.* || 3.2.* || 3.3.* || 3.4.* || ^4.0",
29-
"livewire/livewire": "^2.0"
26+
"php": "^8.1",
27+
"illuminate/support": "^10.0",
28+
"statamic/cms": "^4.0",
29+
"livewire/livewire": "^3.0"
3030
},
3131
"extra": {
3232
"statamic": {

src/Tags/Livewire.php

Lines changed: 31 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,94 +2,54 @@
22

33
namespace Jonassiewertsen\Livewire\Tags;
44

5-
use Illuminate\Support\Str;
65
use Statamic\Tags\Tags;
76

87
class Livewire extends Tags
98
{
109
/**
11-
* This will load your Livewire component in the antlers view
10+
* This will load your Livewire component in the Antlers view
1211
*
1312
* {{ livewire:your-component-name }}
14-
*
15-
* The code has been copied shameless from /Livewire/LivewireBladeDirectives
16-
* A few small changes have been made to output the dom correctly.
17-
*
18-
* @param $expression
19-
* @return mixed
2013
*/
21-
public function wildcard($expression)
14+
public function wildcard($expression): string
2215
{
23-
/**
24-
* Fetching all parameters from our livewire tag, to mount them as livewire parameters.
25-
*/
26-
$parameters = $this->params;
27-
28-
/**
29-
* Let the Livewire magic happen.
30-
*/
31-
$lastArg = trim(last(explode(',', $expression)));
32-
33-
if (Str::startsWith($lastArg, 'key(') && Str::endsWith($lastArg, ')')) {
34-
$cachedKey = Str::replaceFirst('key(', '', Str::replaceLast(')', '', $lastArg));
35-
$args = explode(',', $expression);
36-
array_pop($args);
37-
$expression = implode(',', $args);
38-
} else {
39-
$cachedKey = "'" . Str::random(7) . "'";
40-
}
41-
42-
if (! isset($_instance)) {
43-
$html = \Livewire\Livewire::mount($expression, $parameters->toArray())->html();
44-
} elseif ($_instance->childHasBeenRendered($cachedKey)) {
45-
$componentId = $_instance->getRenderedChildComponentId($cachedKey);
46-
$componentTag = $_instance->getRenderedChildComponentTagName($cachedKey);
47-
$html = \Livewire\Livewire::dummyMount($componentId, $componentTag);
48-
$_instance->preserveRenderedChild($cachedKey);
49-
} else {
50-
$response = \Livewire\Livewire::mount($expression, $parameters->toArray());
51-
$html = $response->html();
52-
$_instance->logRenderedChild($cachedKey, $response->id(), \Livewire\Livewire::getRootElementTagName($html));
53-
}
54-
return $html;
16+
return \Livewire\Livewire::mount($expression, $this->params->toArray());
5517
}
5618

5719
/**
5820
* Sharing State Between Livewire And Alpine via entangle.
59-
* https://laravel-livewire.com/docs/2.x/alpine-js#extracting-blade-components
60-
*
61-
* * The method is a small variation from /Livewire/LivewireBladeDirectives
62-
* A few small changes had to be made to get the correct output.
6321
*
64-
* {{ livewire:entangle property='showDropdown' }}
22+
* {{ livewire:entangle property="showDropdown" modifier="live" }}
6523
*/
6624
public function entangle(): string
6725
{
68-
$expression = $this->params->get('property');
69-
$instanceId = $this->context['_instance']->id;
26+
$property = $this->params->get('property');
27+
$modifier = $this->params->get('modifier');
28+
$instanceId = $this->context['__livewire']->getId();
7029

71-
if ((object) $expression instanceof \Livewire\WireDirective)
72-
{
73-
$value = $expression->value();
74-
$modifier = $expression->hasModifier('defer') ? '.defer' : '';
30+
$expression = ".entangle('{$property}')";
7531

76-
return "window.Livewire.find('{$instanceId}').entangle('{$value}'){$modifier}";
32+
if ($modifier) {
33+
$expression .= ".{$modifier}";
7734
}
7835

79-
return "window.Livewire.find('{$instanceId}').entangle('{$expression}')";
36+
return "window.Livewire.find('$instanceId'){$expression}";
8037
}
8138

8239
/**
8340
* Accessing the Livewire component.
8441
*
85-
* The method is a small variation from /Livewire/LivewireBladeDirectives
86-
* A few small changes had to be made to get the correct output.
87-
*
42+
* {{ livewire:this }}
8843
* {{ livewire:this set="('name', 'Jack')" }}
8944
*/
9045
public function this(): string
9146
{
92-
$instanceId = $this->context['_instance']->id;
47+
$instanceId = $this->context['__livewire']->getId();
48+
49+
if (!count($this->params)) {
50+
return "window.Livewire.find('{$instanceId}')";
51+
}
52+
9353
$action = $this->params->take(1)->toArray();
9454
$method = key($action);
9555
$parameters = reset($action);
@@ -104,16 +64,26 @@ public function this(): string
10464
*/
10565
public function styles(): string
10666
{
107-
return \Livewire\Livewire::styles();
67+
return \Livewire\Mechanisms\FrontendAssets\FrontendAssets::styles();
10868
}
10969

11070
/**
111-
* Loading the livewire styles in antlers style
71+
* Loading the livewire scripts in antlers style
11272
*
11373
* {{ livewire:scripts }}
11474
*/
11575
public function scripts(): string
11676
{
117-
return \Livewire\Livewire::scripts();
77+
return \Livewire\Mechanisms\FrontendAssets\FrontendAssets::scripts();
78+
}
79+
80+
/**
81+
* Prevent livewire from auto-injecting styles and scripts
82+
*
83+
* {{ livewire:scriptConfig }}
84+
*/
85+
public function scriptConfig(): string
86+
{
87+
return \Livewire\Mechanisms\FrontendAssets\FrontendAssets::scriptConfig();
11888
}
11989
}

src/WithPagination.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ trait WithPagination
66
{
77
use \Livewire\WithPagination;
88

9-
public function withPagination($key, $paginator)
9+
public function withPagination($key, $paginator): array
1010
{
1111
return [
1212
$key => $paginator->items(),

0 commit comments

Comments
 (0)