-
Notifications
You must be signed in to change notification settings - Fork 53
/
Copy pathvaadin-router-navigation-trigger-demos.html
200 lines (187 loc) · 8.28 KB
/
vaadin-router-navigation-trigger-demos.html
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<dom-module id="vaadin-router-navigation-trigger-demos">
<template>
<style include="vaadin-component-demo-shared-styles vaadin-router-demo-shared-styles">
:host {
display: block;
}
</style>
<h3>Navigation Triggers</h3>
<p class="note">
This feature is for advanced use cases. Please make sure to read the
documentation carefully.
</p>
<p>
There are several events that can trigger in-app navigation with
Vaadin Router: popstate events, clicks on the <code><a></code>
elements, imperative navigation triggered by JavaScript. In order to make
a flexible solution that can be tweaked to particular app needs and remain
efficient, Vaadin Router has a concept of pluggable <em>Navigation
Triggers</em> that listen to specific browser events and convert them into
the Vaadin Router navigation events.
</p>
<p>
The <code>@vaadin/router</code> package comes with two Navigation
Triggers bundled by default: <code>POPSTATE</code> and <code>CLICK</code>.
</p>
<p>
Developers can define and use additional Navigation Triggers that are
specific to their application. A Navigation Trigger object must have
two methods: <code>activate()</code> to start listening on some UI events,
and <code>inactivate()</code> to stop.
</p>
<h3><code>NavigationTrigger.POPSTATE</code></h3>
<p>
The default <code>POPSTATE</code> navigation trigger for Vaadin Router
listens to <code>popstate</code> events on the current <code>window</code>
and for each of them dispatches a navigation event for Vaadin Router
using the current <code>window.location.pathname</code> as the navigation
target. This allows using the browser Forward and Back buttons for in-app
navigation.
</p>
<p>
In the demo below the <code>popstate</code> events are dispatched at 3
seconds intervals. Before dispatching an event the global <code>
location.pathname</code> is toggled between '/' and '/users'.
</p>
<p>
Please note that when using the <code>window.history.pushState()</code> or
<code>window.history.replaceState()</code> methods, you need to dispatch
the <code>popstate</code> event manually—these methods do not do
that by themselves (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/History_API"
target="_blank" rel="noopener">MDN</a> for details).
</p>
<vaadin-demo-snippet id="vaadin-router-navigation-trigger-demo-1" iframe-src="iframe.html">
<template preserve-content>
<div id="outlet"></div>
<script>
// import {Router} from '@vaadin/router'; // for Webpack / Polymer CLI
// const Router = Vaadin.Router; // for vaadin-router.umd.js
const router = new Router(document.getElementById('outlet'));
router.setRoutes([
{path: '/', component: 'x-home-view'},
{path: '/users', component: 'x-user-list'},
]);
setInterval(() => {
window.history.pushState(null, document.title,
window.location.pathname !== '/' ? '/' : '/users');
window.dispatchEvent(new PopStateEvent('popstate'));
}, 3000);
</script>
</template>
</vaadin-demo-snippet>
<h3><code>NavigationTrigger.CLICK</code></h3>
<p>
The <code>CLICK</code> navigation trigger intercepts clicks on
<code><a></code> elements on the the page and converts them into
navigation events for Vaadin Router if they refer to a
location within the app. That allows using regular <code><a></code>
link elements for in-app navigation. You can use <code>router-ignore</code>
attribute to have the router ignore the link.
</p>
<vaadin-demo-snippet id="vaadin-router-navigation-trigger-demo-2" iframe-src="iframe.html">
<template preserve-content>
<a href="/">Home</a>
<a href="/users">Users</a>
<div id="outlet"></div>
<script>
// import {Router} from '@vaadin/router'; // for Webpack / Polymer CLI
// const Router = Vaadin.Router; // for vaadin-router.umd.js
const router = new Router(document.getElementById('outlet'));
router.setRoutes([
{path: '/', component: 'x-home-view'},
{path: '/users', component: 'x-user-list'},
]);
</script>
</template>
</vaadin-demo-snippet>
<h3>Custom Navigation Triggers</h3>
<p>
The set of default navigation triggers can be changed using the <code>
Router.setTriggers()</code> static method. It accepts zero, one or more
<code>NavigationTrigger</code>s.
</p>
<p>
This demo shows how to disable the <code>CLICK</code> navigation trigger.
It may be useful when the app has an own custom element for in-app links
instead of using the regular <code><a></code> elements for that
purpose. The demo also shows a very basic version of a custom in-app link
element based on a list element that fires <code>popstate</code> events
when clicked.
</p>
<p>
Note: if the default Navigation Triggers are not used by the app, they can
be excluded from the app bundle to avoid sending unnecessary code to the
users. See <code>src/router-config.js</code> for details.
</p>
<vaadin-demo-snippet id="vaadin-router-navigation-trigger-demo-3" iframe-src="iframe.html">
<template preserve-content>
<ul>
<li data-href="/">Home</li>
<li data-href="/users">Users</li>
</ul>
<div id="outlet"></div>
<script>
// import {Router} from '@vaadin/router'; // for Webpack / Polymer CLI
// const Router = Vaadin.Router; // for vaadin-router.umd.js
const {POPSTATE} = Router.NavigationTrigger;
Router.setTriggers(POPSTATE);
document.querySelector('ul').addEventListener('click', event => {
const target = event.target;
if (target.localName === 'li' && target.dataset.href) {
window.history.pushState({}, null, target.dataset.href);
window.dispatchEvent(new PopStateEvent('popstate'));
}
});
const router = new Router(document.getElementById('outlet'));
router.setRoutes([
{path: '/', component: 'x-home-view'},
{path: '/users', component: 'x-user-list'},
]);
</script>
</template>
</vaadin-demo-snippet>
<h3>Unsubscribe from Navigation Events</h3>
<p>
Each Vaadin Router instance is automatically subscribed to navigation
events upon creation. Sometimes it might be necessary to cancel this
subscription so that the router would re-render only in response to the
explicit <code>render()</code> method calls. Use the <code>unsubscribe()
</code> method to cancel this automatic subscription and the <code>
subscribe()</code> method to re-subscribe.
</p>
<vaadin-demo-snippet id="vaadin-router-navigation-trigger-demo-4" iframe-src="iframe.html">
<template preserve-content>
<a href="/">Home</a>
<a href="/users">Users</a>
<div id="outlet"></div>
<script>
// import {Router} from '@vaadin/router'; // for Webpack / Polymer CLI
// const Router = Vaadin.Router; // for vaadin-router.umd.js
const router = new Router(document.getElementById('outlet'));
router.setRoutes([
{path: '/', component: 'x-home-view'},
{path: '/users',
children: [
{path: '/', component: 'x-user-list'},
{path: '/:user', component: 'x-user-profile'}
]
},
]);
router.unsubscribe();
// router will re-render only when the `render()` method is called explicitly:
router.render('/users');
</script>
</template>
</vaadin-demo-snippet>
</template>
<script>
class VaadinRouterNavigationTriggerDemos
extends DemoReadyEventEmitter(ElementDemo(Polymer.Element)) {
static get is() {
return 'vaadin-router-navigation-trigger-demos';
}
}
customElements.define(VaadinRouterNavigationTriggerDemos.is,
VaadinRouterNavigationTriggerDemos);
</script>
</dom-module>