Skip to content

Commit 6b629c5

Browse files
committed
feature #20 Add option to set swup main element via data attribute (optior)
This PR was merged into the 2.x branch. Discussion ---------- Add option to set swup main element via data attribute | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Tickets | | License | MIT This pull request adds the possibility to change the `mainElement` of the swup theme. For this purpose the new data attribute `data-main-element` is introduced. Commits ------- beb1f98 Add option to set swup main element
2 parents ca7f933 + beb1f98 commit 6b629c5

File tree

3 files changed

+178
-22
lines changed

3 files changed

+178
-22
lines changed

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

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,24 @@ import SwupSlideTheme from '@swup/slide-theme';
77

88
class default_1 extends Controller {
99
connect() {
10+
const dataContainers = this.containersValue;
11+
const mainElement = this.mainElementValue || dataContainers[0] || '#swup';
12+
const allElements = [mainElement].concat(dataContainers);
13+
const containersList = allElements.filter((item, index) => {
14+
return allElements.indexOf(item) === index;
15+
});
1016
const options = {
11-
containers: ['#swup'],
12-
plugins: ['slide' === this.themeValue ? new SwupSlideTheme() : new SwupFadeTheme(), new SwupFormsPlugin()],
17+
containers: containersList,
18+
plugins: [
19+
'slide' === this.themeValue
20+
? new SwupSlideTheme({ mainElement: mainElement })
21+
: new SwupFadeTheme({ mainElement: mainElement }),
22+
new SwupFormsPlugin(),
23+
],
1324
};
25+
if (this.hasMainElementValue) {
26+
options.mainElement = this.mainElementValue;
27+
}
1428
if (this.hasAnimateHistoryBrowsingValue) {
1529
options.animateHistoryBrowsing = this.animateHistoryBrowsingValue;
1630
}
@@ -20,9 +34,6 @@ class default_1 extends Controller {
2034
if (this.hasCacheValue) {
2135
options.cache = this.cacheValue;
2236
}
23-
if (this.hasContainersValue) {
24-
options.containers = this.containersValue;
25-
}
2637
if (this.hasLinkSelectorValue) {
2738
options.linkSelector = this.linkSelectorValue;
2839
}
@@ -45,6 +56,7 @@ default_1.values = {
4556
linkSelector: String,
4657
theme: String,
4758
debug: Boolean,
59+
mainElement: String,
4860
};
4961

5062
export { default_1 as default };

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

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export default class extends Controller {
2424
cacheValue: boolean;
2525
hasCacheValue: boolean;
2626
containersValue: string[];
27-
hasContainersValue: boolean;
27+
mainElementValue: string;
28+
hasMainElementValue: boolean;
2829
linkSelectorValue: string;
2930
hasLinkSelectorValue: boolean;
3031
themeValue: string;
@@ -40,14 +41,31 @@ export default class extends Controller {
4041
// custom values
4142
theme: String,
4243
debug: Boolean,
44+
mainElement: String,
4345
};
4446

4547
connect() {
48+
const dataContainers = this.containersValue;
49+
const mainElement = this.mainElementValue || dataContainers[0] || '#swup';
50+
const allElements = [mainElement].concat(dataContainers);
51+
const containersList = allElements.filter((item, index) => {
52+
return allElements.indexOf(item) === index;
53+
});
54+
4655
const options: any = {
47-
containers: ['#swup'],
48-
plugins: ['slide' === this.themeValue ? new SwupSlideTheme() : new SwupFadeTheme(), new SwupFormsPlugin()],
56+
containers: containersList,
57+
plugins: [
58+
'slide' === this.themeValue
59+
? new SwupSlideTheme({ mainElement: mainElement })
60+
: new SwupFadeTheme({ mainElement: mainElement }),
61+
new SwupFormsPlugin(),
62+
],
4963
};
5064

65+
if (this.hasMainElementValue) {
66+
options.mainElement = this.mainElementValue;
67+
}
68+
5169
if (this.hasAnimateHistoryBrowsingValue) {
5270
options.animateHistoryBrowsing = this.animateHistoryBrowsingValue;
5371
}
@@ -57,9 +75,6 @@ export default class extends Controller {
5775
if (this.hasCacheValue) {
5876
options.cache = this.cacheValue;
5977
}
60-
if (this.hasContainersValue) {
61-
options.containers = this.containersValue;
62-
}
6378
if (this.hasLinkSelectorValue) {
6479
options.linkSelector = this.linkSelectorValue;
6580
}

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

Lines changed: 140 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@ const startStimulus = () => {
3636
};
3737

3838
describe('SwupController', () => {
39-
let container;
39+
afterEach(() => {
40+
clearDOM();
41+
actualSwupOptions = null;
42+
});
4043

41-
beforeEach(() => {
42-
container = mountDOM(`
44+
it('connect', async () => {
45+
const container = mountDOM(`
4346
<html>
4447
<head>
4548
<title>Symfony UX</title>
@@ -62,14 +65,6 @@ describe('SwupController', () => {
6265
</body>
6366
</html>
6467
`);
65-
});
66-
67-
afterEach(() => {
68-
clearDOM();
69-
actualSwupOptions = null;
70-
});
71-
72-
it('connect', async () => {
7368
const bodyElement = getByTestId(container, 'body');
7469
expect(bodyElement).not.toHaveClass('connected');
7570

@@ -81,4 +76,138 @@ describe('SwupController', () => {
8176
expect(actualSwupOptions.cache).toBe(true);
8277
expect(actualSwupOptions.animateHistoryBrowsing).toBe(true);
8378
});
79+
80+
it('neither main element nor containers provided', async () => {
81+
const container = mountDOM(`
82+
<html>
83+
<head>
84+
<title>Symfony UX</title>
85+
</head>
86+
<body>
87+
<div
88+
data-testid="body"
89+
data-controller="check swup"
90+
data-swup-link-selector-value="a"
91+
data-swup-animation-selector-value="[transition-*]"
92+
data-swup-debug-value="data-debug"
93+
data-swup-cache-value="data-cache"
94+
data-swup-animate-history-browsing-value="data-animate-history-browsing">
95+
<div id="nav"></div>
96+
<div id="swup">
97+
<a href="/">Link</a>
98+
</div>
99+
</div>
100+
</body>
101+
</html>
102+
`);
103+
const bodyElement = getByTestId(container, 'body');
104+
expect(bodyElement).not.toHaveClass('connected');
105+
106+
startStimulus();
107+
await waitFor(() => expect(bodyElement).toHaveClass('connected'));
108+
expect(actualSwupOptions.mainElement).toEqual(undefined);
109+
expect(actualSwupOptions.containers).toEqual(['#swup']);
110+
});
111+
112+
it('only data-main-element is provided,', async () => {
113+
const container = mountDOM(`
114+
<html>
115+
<head>
116+
<title>Symfony UX</title>
117+
</head>
118+
<body>
119+
<div
120+
data-testid="body"
121+
data-controller="check swup"
122+
data-swup-main-element-value="#main"
123+
data-swup-link-selector-value="a"
124+
data-swup-animation-selector-value="[transition-*]"
125+
data-swup-debug-value="data-debug"
126+
data-swup-cache-value="data-cache"
127+
data-swup-animate-history-browsing-value="data-animate-history-browsing">
128+
<div id="nav"></div>
129+
<div id="main"></div>
130+
<div id="swup">
131+
<a href="/">Link</a>
132+
</div>
133+
</div>
134+
</body>
135+
</html>
136+
`);
137+
const bodyElement = getByTestId(container, 'body');
138+
expect(bodyElement).not.toHaveClass('connected');
139+
140+
startStimulus();
141+
await waitFor(() => expect(bodyElement).toHaveClass('connected'));
142+
expect(actualSwupOptions.mainElement).toEqual('#main');
143+
expect(actualSwupOptions.containers).toEqual(['#main']);
144+
});
145+
146+
it('only data-containers provided', async () => {
147+
const container = mountDOM(`
148+
<html>
149+
<head>
150+
<title>Symfony UX</title>
151+
</head>
152+
<body>
153+
<div
154+
data-testid="body"
155+
data-controller="check swup"
156+
data-swup-containers-value="[&quot;#swup&quot;, &quot;#nav&quot;]"
157+
data-swup-link-selector-value="a"
158+
data-swup-animation-selector-value="[transition-*]"
159+
data-swup-debug-value="data-debug"
160+
data-swup-cache-value="data-cache"
161+
data-swup-animate-history-browsing-value="data-animate-history-browsing">
162+
<div id="nav"></div>
163+
<div id="swup">
164+
<a href="/">Link</a>
165+
</div>
166+
</div>
167+
</body>
168+
</html>
169+
`);
170+
const bodyElement = getByTestId(container, 'body');
171+
expect(bodyElement).not.toHaveClass('connected');
172+
173+
startStimulus();
174+
await waitFor(() => expect(bodyElement).toHaveClass('connected'));
175+
expect(actualSwupOptions.mainElement).toEqual(undefined);
176+
expect(actualSwupOptions.containers).toEqual(['#swup', '#nav']);
177+
});
178+
179+
it('data-main-element and data-containers are provided,', async () => {
180+
const container = mountDOM(`
181+
<html>
182+
<head>
183+
<title>Symfony UX</title>
184+
</head>
185+
<body>
186+
<div
187+
data-testid="body"
188+
data-controller="check swup"
189+
data-swup-main-element-value="#main"
190+
data-swup-containers-value="[&quot;#swup&quot;, &quot;#nav&quot;]"
191+
data-swup-link-selector-value="a"
192+
data-swup-animation-selector-value="[transition-*]"
193+
data-swup-debug-value="data-debug"
194+
data-swup-cache-value="data-cache"
195+
data-swup-animate-history-browsing-value="data-animate-history-browsing">
196+
<div id="nav"></div>
197+
<div id="main"></div>
198+
<div id="swup">
199+
<a href="/">Link</a>
200+
</div>
201+
</div>
202+
</body>
203+
</html>
204+
`);
205+
const bodyElement = getByTestId(container, 'body');
206+
expect(bodyElement).not.toHaveClass('connected');
207+
208+
startStimulus();
209+
await waitFor(() => expect(bodyElement).toHaveClass('connected'));
210+
expect(actualSwupOptions.mainElement).toEqual('#main');
211+
expect(actualSwupOptions.containers).toEqual(['#main', '#swup', '#nav']);
212+
});
84213
});

0 commit comments

Comments
 (0)