Skip to content

[Swup] Convert options to values #192

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/Swup/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
- Support for `stimulus` version 2 was removed and support for `@hotwired/stimulus`
version 3 was added. See the [@symfony/stimulus-bridge CHANGELOG](https://github.com/symfony/stimulus-bridge/blob/main/CHANGELOG.md#300)
for more details.
- Support added for Symfony 6
- All options were changed from `data-` attributes to Stimulus values. See
The README for updated instructions.
- Added a new `swup:pre-connect` event.
- Support added for Symfony 6.

## 1.3

Expand Down
39 changes: 29 additions & 10 deletions src/Swup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ additional containers, for instance to have a navigation menu that updates when
{% endblock %}
</head>
<body
{{ stimulus_controller('symfony/ux-swup/swup') }}
data-containers="#swup #nav" {# list of selectors separated by spaces #}
{{ stimulus_controller('symfony/ux-swup/swup', {
containers: ['#swup', '#nav']
}) }}
>
{# ... #}

Expand All @@ -88,26 +89,37 @@ additional containers, for instance to have a navigation menu that updates when
</html>
```

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

```twig
<html lang="en">
<head>
<title>Swup</title>
</head>
<body
{{ stimulus_controller('symfony/ux-swup/swup') }}
data-containers="#swup #nav"
data-theme="slide" {# or "fade", the default #}
data-debug="data-debug" {# add this attribute to enable debug #}
data-cache="data-cache" {# add this attribute to enable local cache: be careful, it only makes sense for mostly static websites #}
data-animate-history-browsing="data-animate-history-browsing" {# add this attribute to animate history browsing #}
{{ stimulus_controller('symfony/ux-swup/swup', {
containers: ['#swup', '#nav'],
animateHistoryBrowsing: true
animationSelector: '[class*="transition-"]',
cache: true,
linkSelector: '...',

theme: 'slide',
debug: true,
}) }}
>
{# ... #}
</body>
</html>
```

The extra options are:

- `theme`: either `slide` or `fade` (the default);
- `debug`: add this attribute to enable debug.

### Extend the default behavior

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

export default class extends Controller {
connect() {
this.element.addEventListener('swup:pre-connect', this._onPreConnect);
this.element.addEventListener('swup:connect', this._onConnect);
}

disconnect() {
// You should always remove listeners when the controller is disconnected to avoid side-effects
this.element.removeEventListener('swup:connect', this._onConnect);
this.element.removeEventListener('swup:pre-connect', this._onConnect);
this.element.removeEventListener('swup:connect', this._onPreConnect);
}

_onPreConnect(event) {
// Swup has not been initialized - options can be changed
console.log(event.detail.options); // Options that will be used to initialize Swup
}

_onConnect(event) {
Expand Down
41 changes: 26 additions & 15 deletions src/Swup/Resources/assets/dist/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,31 @@ import SwupFormsPlugin from '@swup/forms-plugin';
import SwupFadeTheme from '@swup/fade-theme';
import SwupSlideTheme from '@swup/slide-theme';

class controller extends Controller {
class default_1 extends Controller {
connect() {
const options = {
containers: ['#swup'],
cache: this.element.hasAttribute('data-cache'),
animateHistoryBrowsing: this.element.hasAttribute('data-animate-history-browsing'),
plugins: [
'slide' === this.element.getAttribute('data-theme') ? new SwupSlideTheme() : new SwupFadeTheme(),
new SwupFormsPlugin(),
],
plugins: ['slide' === this.themeValue ? new SwupSlideTheme() : new SwupFadeTheme(), new SwupFormsPlugin()],
};
if (this.element.getAttribute('data-containers')) {
options.containers = this.element.getAttribute('data-containers').split(' ');
if (this.hasAnimateHistoryBrowsingValue) {
options.animateHistoryBrowsing = this.animateHistoryBrowsingValue;
}
if (this.element.getAttribute('data-link-selector')) {
options.linkSelector = this.element.getAttribute('data-link-selector');
if (this.hasAnimationSelectorValue) {
options.animationSelector = this.animationSelectorValue;
}
if (this.element.getAttribute('data-animation-selector')) {
options.animationSelector = this.element.getAttribute('data-animation-selector');
if (this.hasCacheValue) {
options.cache = this.cacheValue;
}
if (this.element.hasAttribute('data-debug')) {
if (this.hasContainersValue) {
options.containers = this.containersValue;
}
if (this.hasLinkSelectorValue) {
options.linkSelector = this.linkSelectorValue;
}
if (this.debugValue) {
options.plugins.push(new SwupDebugPlugin());
}
this._dispatchEvent('swup:pre-connect', { options });
const swup = new Swup(options);
this._dispatchEvent('swup:connect', { swup, options });
}
Expand All @@ -37,5 +39,14 @@ class controller extends Controller {
this.element.dispatchEvent(userEvent);
}
}
default_1.values = {
animateHistoryBrowsing: Boolean,
animationSelector: String,
cache: Boolean,
containers: Array,
linkSelector: String,
theme: String,
debug: Boolean,
};

export { controller as default };
export { default_1 as default };
44 changes: 28 additions & 16 deletions src/Swup/Resources/assets/src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,45 @@ import SwupFadeTheme from '@swup/fade-theme';
import SwupSlideTheme from '@swup/slide-theme';

export default class extends Controller {
static values = {
animateHistoryBrowsing: Boolean,
animationSelector: String,
cache: Boolean,
containers: Array,
linkSelector: String,

// custom values
theme: String,
debug: Boolean,
};

connect() {
const options = {
containers: ['#swup'],
cache: this.element.hasAttribute('data-cache'),
animateHistoryBrowsing: this.element.hasAttribute('data-animate-history-browsing'),
plugins: [
'slide' === this.element.getAttribute('data-theme') ? new SwupSlideTheme() : new SwupFadeTheme(),
new SwupFormsPlugin(),
],
plugins: ['slide' === this.themeValue ? new SwupSlideTheme() : new SwupFadeTheme(), new SwupFormsPlugin()],
};

if (this.element.getAttribute('data-containers')) {
options.containers = this.element.getAttribute('data-containers').split(' ');
if (this.hasAnimateHistoryBrowsingValue) {
options.animateHistoryBrowsing = this.animateHistoryBrowsingValue;
}

if (this.element.getAttribute('data-link-selector')) {
options.linkSelector = this.element.getAttribute('data-link-selector');
if (this.hasAnimationSelectorValue) {
options.animationSelector = this.animationSelectorValue;
}

if (this.element.getAttribute('data-animation-selector')) {
options.animationSelector = this.element.getAttribute('data-animation-selector');
if (this.hasCacheValue) {
options.cache = this.cacheValue;
}

if (this.element.hasAttribute('data-debug')) {
if (this.hasContainersValue) {
options.containers = this.containersValue;
}
if (this.hasLinkSelectorValue) {
options.linkSelector = this.linkSelectorValue;
}
if (this.debugValue) {
options.plugins.push(new SwupDebugPlugin());
}

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

const swup = new Swup(options);

this._dispatchEvent('swup:connect', { swup, options });
Expand Down
29 changes: 21 additions & 8 deletions src/Swup/Resources/assets/test/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ import { getByTestId, waitFor } from '@testing-library/dom';
import { clearDOM, mountDOM } from '@symfony/stimulus-testing';
import SwupController from '../src/controller';

let actualSwupOptions: any = null;

// Controller used to check the actual controller was properly booted
class CheckController extends Controller {
connect() {
this.element.addEventListener('swup:pre-connect', (event) => {
actualSwupOptions = event.detail.options;
});

this.element.addEventListener('swup:connect', () => {
this.element.classList.add('connected');
});
Expand All @@ -42,12 +48,12 @@ describe('SwupController', () => {
<div
data-testid="body"
data-controller="check swup"
data-containers="#swup #nav"
data-link-selector="a"
data-animation-selector="[transition-*]"
data-debug="data-debug"
data-cache="data-cache"
data-animate-history-browsing="data-animate-history-browsing">
data-swup-containers-value="[&quot;#swup&quot;, &quot;#nav&quot;]"
data-swup-link-selector-value="a"
data-swup-animation-selector-value="[transition-*]"
data-swup-debug-value="data-debug"
data-swup-cache-value="data-cache"
data-swup-animate-history-browsing-value="data-animate-history-browsing">
<div id="nav"></div>
<div id="swup">
<a href="/">Link</a>
Expand All @@ -60,12 +66,19 @@ describe('SwupController', () => {

afterEach(() => {
clearDOM();
actualSwupOptions = null;
});

it('connect', async () => {
expect(getByTestId(container, 'body')).not.toHaveClass('connected');
const bodyElement = getByTestId(container, 'body');
expect(bodyElement).not.toHaveClass('connected');

startStimulus();
await waitFor(() => expect(getByTestId(container, 'body')).toHaveClass('connected'));
await waitFor(() => expect(bodyElement).toHaveClass('connected'));
expect(actualSwupOptions.containers).toEqual(['#swup', '#nav']);
expect(actualSwupOptions.linkSelector).toBe('a');
expect(actualSwupOptions.animationSelector).toBe('[transition-*]');
expect(actualSwupOptions.cache).toBe(true);
expect(actualSwupOptions.animateHistoryBrowsing).toBe(true);
});
});