Skip to content

Commit 257d480

Browse files
committed
[Swup] Converting options to values
1 parent a3da92d commit 257d480

File tree

5 files changed

+108
-50
lines changed

5 files changed

+108
-50
lines changed

src/Swup/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
66
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
77
for more details.
8-
- Support added for Symfony 6
8+
- All options were changed from `data-` attributes to Stimulus values. See
9+
The README for updated instructions.
10+
- Added a new `swup:pre-connect` event.
11+
- Support added for Symfony 6.
912

1013
## 1.3
1114

src/Swup/README.md

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ additional containers, for instance to have a navigation menu that updates when
7272
{% endblock %}
7373
</head>
7474
<body
75-
{{ stimulus_controller('symfony/ux-swup/swup') }}
76-
data-containers="#swup #nav" {# list of selectors separated by spaces #}
75+
{{ stimulus_controller('symfony/ux-swup/swup', {
76+
containers: ['#swup', '#nav']
77+
}) }}
7778
>
7879
{# ... #}
7980
@@ -88,26 +89,37 @@ additional containers, for instance to have a navigation menu that updates when
8889
</html>
8990
```
9091

91-
You can configure several other options using data-attributes on the `body` tag:
92+
You can configure several other options using values on the controller.
93+
Most of these correspond to [Swup Options](https://swup.js.org/options),
94+
but there are a few extra added:
9295

9396
```twig
9497
<html lang="en">
9598
<head>
9699
<title>Swup</title>
97100
</head>
98101
<body
99-
{{ stimulus_controller('symfony/ux-swup/swup') }}
100-
data-containers="#swup #nav"
101-
data-theme="slide" {# or "fade", the default #}
102-
data-debug="data-debug" {# add this attribute to enable debug #}
103-
data-cache="data-cache" {# add this attribute to enable local cache: be careful, it only makes sense for mostly static websites #}
104-
data-animate-history-browsing="data-animate-history-browsing" {# add this attribute to animate history browsing #}
102+
{{ stimulus_controller('symfony/ux-swup/swup', {
103+
containers: ['#swup', '#nav'],
104+
animateHistoryBrowsing: true
105+
animationSelector: '[class*="transition-"]',
106+
cache: true,
107+
linkSelector: '...',
108+
109+
theme: 'slide',
110+
debug: true,
111+
}) }}
105112
>
106113
{# ... #}
107114
</body>
108115
</html>
109116
```
110117

118+
The extra options are:
119+
120+
- `theme`: either `slide` or `fade` (the default);
121+
- `debug`: add this attribute to enable debug.
122+
111123
### Extend the default behavior
112124

113125
Symfony UX Swup allows you to extend its default behavior using a custom Stimulus controller:
@@ -119,12 +131,19 @@ import { Controller } from '@hotwired/stimulus';
119131

120132
export default class extends Controller {
121133
connect() {
134+
this.element.addEventListener('swup:pre-connect', this._onPreConnect);
122135
this.element.addEventListener('swup:connect', this._onConnect);
123136
}
124137

125138
disconnect() {
126139
// You should always remove listeners when the controller is disconnected to avoid side-effects
127-
this.element.removeEventListener('swup:connect', this._onConnect);
140+
this.element.removeEventListener('swup:pre-connect', this._onConnect);
141+
this.element.removeEventListener('swup:connect', this._onPreConnect);
142+
}
143+
144+
_onPreConnect(event) {
145+
// Swup has not been initialized - options can be changed
146+
console.log(event.detail.options); // Options that will be used to initialize Swup
128147
}
129148

130149
_onConnect(event) {

src/Swup/Resources/assets/dist/controller.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,31 @@ import SwupFormsPlugin from '@swup/forms-plugin';
55
import SwupFadeTheme from '@swup/fade-theme';
66
import SwupSlideTheme from '@swup/slide-theme';
77

8-
class controller extends Controller {
8+
class default_1 extends Controller {
99
connect() {
1010
const options = {
1111
containers: ['#swup'],
12-
cache: this.element.hasAttribute('data-cache'),
13-
animateHistoryBrowsing: this.element.hasAttribute('data-animate-history-browsing'),
14-
plugins: [
15-
'slide' === this.element.getAttribute('data-theme') ? new SwupSlideTheme() : new SwupFadeTheme(),
16-
new SwupFormsPlugin(),
17-
],
12+
plugins: ['slide' === this.themeValue ? new SwupSlideTheme() : new SwupFadeTheme(), new SwupFormsPlugin()],
1813
};
19-
if (this.element.getAttribute('data-containers')) {
20-
options.containers = this.element.getAttribute('data-containers').split(' ');
14+
if (this.hasAnimateHistoryBrowsingValue) {
15+
options.animateHistoryBrowsing = this.animateHistoryBrowsingValue;
2116
}
22-
if (this.element.getAttribute('data-link-selector')) {
23-
options.linkSelector = this.element.getAttribute('data-link-selector');
17+
if (this.hasAnimationSelectorValue) {
18+
options.animationSelector = this.animationSelectorValue;
2419
}
25-
if (this.element.getAttribute('data-animation-selector')) {
26-
options.animationSelector = this.element.getAttribute('data-animation-selector');
20+
if (this.hasCacheValue) {
21+
options.cache = this.cacheValue;
2722
}
28-
if (this.element.hasAttribute('data-debug')) {
23+
if (this.hasContainersValue) {
24+
options.containers = this.containersValue;
25+
}
26+
if (this.hasLinkSelectorValue) {
27+
options.linkSelector = this.linkSelectorValue;
28+
}
29+
if (this.debugValue) {
2930
options.plugins.push(new SwupDebugPlugin());
3031
}
32+
this._dispatchEvent('swup:pre-connect', { options });
3133
const swup = new Swup(options);
3234
this._dispatchEvent('swup:connect', { swup, options });
3335
}
@@ -37,5 +39,14 @@ class controller extends Controller {
3739
this.element.dispatchEvent(userEvent);
3840
}
3941
}
42+
default_1.values = {
43+
animateHistoryBrowsing: Boolean,
44+
animationSelector: String,
45+
cache: Boolean,
46+
containers: Array,
47+
linkSelector: String,
48+
theme: String,
49+
debug: Boolean,
50+
};
4051

41-
export { controller as default };
52+
export { default_1 as default };

src/Swup/Resources/assets/src/controller.ts

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,45 @@ import SwupFadeTheme from '@swup/fade-theme';
1717
import SwupSlideTheme from '@swup/slide-theme';
1818

1919
export default class extends Controller {
20+
static values = {
21+
animateHistoryBrowsing: Boolean,
22+
animationSelector: String,
23+
cache: Boolean,
24+
containers: Array,
25+
linkSelector: String,
26+
27+
// custom values
28+
theme: String,
29+
debug: Boolean,
30+
};
31+
2032
connect() {
2133
const options = {
2234
containers: ['#swup'],
23-
cache: this.element.hasAttribute('data-cache'),
24-
animateHistoryBrowsing: this.element.hasAttribute('data-animate-history-browsing'),
25-
plugins: [
26-
'slide' === this.element.getAttribute('data-theme') ? new SwupSlideTheme() : new SwupFadeTheme(),
27-
new SwupFormsPlugin(),
28-
],
35+
plugins: ['slide' === this.themeValue ? new SwupSlideTheme() : new SwupFadeTheme(), new SwupFormsPlugin()],
2936
};
3037

31-
if (this.element.getAttribute('data-containers')) {
32-
options.containers = this.element.getAttribute('data-containers').split(' ');
38+
if (this.hasAnimateHistoryBrowsingValue) {
39+
options.animateHistoryBrowsing = this.animateHistoryBrowsingValue;
3340
}
34-
35-
if (this.element.getAttribute('data-link-selector')) {
36-
options.linkSelector = this.element.getAttribute('data-link-selector');
41+
if (this.hasAnimationSelectorValue) {
42+
options.animationSelector = this.animationSelectorValue;
3743
}
38-
39-
if (this.element.getAttribute('data-animation-selector')) {
40-
options.animationSelector = this.element.getAttribute('data-animation-selector');
44+
if (this.hasCacheValue) {
45+
options.cache = this.cacheValue;
4146
}
42-
43-
if (this.element.hasAttribute('data-debug')) {
47+
if (this.hasContainersValue) {
48+
options.containers = this.containersValue;
49+
}
50+
if (this.hasLinkSelectorValue) {
51+
options.linkSelector = this.linkSelectorValue;
52+
}
53+
if (this.debugValue) {
4454
options.plugins.push(new SwupDebugPlugin());
4555
}
4656

57+
this._dispatchEvent('swup:pre-connect', { options });
58+
4759
const swup = new Swup(options);
4860

4961
this._dispatchEvent('swup:connect', { swup, options });

src/Swup/Resources/assets/test/controller.test.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,15 @@ import { getByTestId, waitFor } from '@testing-library/dom';
1414
import { clearDOM, mountDOM } from '@symfony/stimulus-testing';
1515
import SwupController from '../src/controller';
1616

17+
let actualSwupOptions: any = null;
18+
1719
// Controller used to check the actual controller was properly booted
1820
class CheckController extends Controller {
1921
connect() {
22+
this.element.addEventListener('swup:pre-connect', (event) => {
23+
actualSwupOptions = event.detail.options;
24+
});
25+
2026
this.element.addEventListener('swup:connect', () => {
2127
this.element.classList.add('connected');
2228
});
@@ -42,12 +48,12 @@ describe('SwupController', () => {
4248
<div
4349
data-testid="body"
4450
data-controller="check swup"
45-
data-containers="#swup #nav"
46-
data-link-selector="a"
47-
data-animation-selector="[transition-*]"
48-
data-debug="data-debug"
49-
data-cache="data-cache"
50-
data-animate-history-browsing="data-animate-history-browsing">
51+
data-swup-containers-value="[&quot;#swup&quot;, &quot;#nav&quot;]"
52+
data-swup-link-selector-value="a"
53+
data-swup-animation-selector-value="[transition-*]"
54+
data-swup-debug-value="data-debug"
55+
data-swup-cache-value="data-cache"
56+
data-swup-animate-history-browsing-value="data-animate-history-browsing">
5157
<div id="nav"></div>
5258
<div id="swup">
5359
<a href="/">Link</a>
@@ -60,12 +66,19 @@ describe('SwupController', () => {
6066

6167
afterEach(() => {
6268
clearDOM();
69+
actualSwupOptions = null;
6370
});
6471

6572
it('connect', async () => {
66-
expect(getByTestId(container, 'body')).not.toHaveClass('connected');
73+
const bodyElement = getByTestId(container, 'body');
74+
expect(bodyElement).not.toHaveClass('connected');
6775

6876
startStimulus();
69-
await waitFor(() => expect(getByTestId(container, 'body')).toHaveClass('connected'));
77+
await waitFor(() => expect(bodyElement).toHaveClass('connected'));
78+
expect(actualSwupOptions.containers).toEqual(['#swup', '#nav']);
79+
expect(actualSwupOptions.linkSelector).toBe('a');
80+
expect(actualSwupOptions.animationSelector).toBe('[transition-*]');
81+
expect(actualSwupOptions.cache).toBe(true);
82+
expect(actualSwupOptions.animateHistoryBrowsing).toBe(true);
7083
});
7184
});

0 commit comments

Comments
 (0)