@ons/design-system 45.2.1 → 46.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,28 +6,20 @@ class AbortableFetch {
6
6
  this.status = 'UNSENT';
7
7
  }
8
8
 
9
- send() {
9
+ async send() {
10
10
  this.status = 'LOADING';
11
-
12
- return new Promise((resolve, reject) => {
13
- abortableFetch(this.url, { signal: this.controller.signal, ...this.options })
14
- .then(response => {
15
- if (response.status >= 200 && response.status < 300) {
16
- this.status = 'DONE';
17
- resolve(response);
18
- } else if (response.status >= 400) {
19
- this.status = 'DONE';
20
- resolve(response);
21
- } else {
22
- this.status = 'DONE';
23
- reject(response);
24
- }
25
- })
26
- .catch(error => {
27
- this.status = 'undefined';
28
- reject(error);
29
- });
30
- });
11
+ try {
12
+ const response = await window.fetch(this.url, { signal: this.controller.signal, ...this.options });
13
+ const isResponseOK = (response.status >= 200 && response.status < 300) || response.status >= 400;
14
+ if (!isResponseOK) {
15
+ const error = new Error(`HTTP error! status: ${response.status}`);
16
+ error.response = response;
17
+ throw error;
18
+ }
19
+ return response;
20
+ } finally {
21
+ this.status = 'DONE';
22
+ }
31
23
  }
32
24
 
33
25
  abort() {
@@ -35,21 +27,4 @@ class AbortableFetch {
35
27
  }
36
28
  }
37
29
 
38
- function abortableFetch(url, options) {
39
- return window
40
- .fetch(url, options)
41
- .then(response => {
42
- if (response) {
43
- return response;
44
- } else {
45
- const error = new Error(response.status);
46
- error.response = response;
47
- throw error;
48
- }
49
- })
50
- .catch(error => {
51
- throw error;
52
- });
53
- }
54
-
55
30
  export default (url, options) => new AbortableFetch(url, options);
package/js/main.js CHANGED
@@ -24,4 +24,5 @@ import '../components/skip-to-content/skip-to-content.dom';
24
24
  import '../components/download-resources/download-resources';
25
25
  import '../components/select/select';
26
26
  import '../components/modal/modal.dom';
27
- import '../components/timeout-modal/timeout.dom';
27
+ import '../components/timeout-modal/timeout-modal.dom';
28
+ import '../components/timeout-panel/timeout-panel.dom';
@@ -1,15 +1,13 @@
1
- import Modal from '../modal/modal';
2
-
3
1
  export default class Timeout {
4
- constructor(context, url, time) {
2
+ constructor(context, sessionExpiryEndpoint, initialExpiryTime, enableTimeoutReset, startOnLoad) {
5
3
  this.context = context;
6
- this.sessionExpiryEndpoint = url;
7
- this.initialExpiryTime = time;
8
- this.continueButton = context.querySelector('.ons-js-modal-btn');
4
+ this.sessionExpiryEndpoint = sessionExpiryEndpoint;
5
+ this.initialExpiryTime = initialExpiryTime;
6
+ this.enableTimeoutReset = enableTimeoutReset || false;
7
+ this.startOnLoad = startOnLoad || false;
9
8
  this.countdown = context.querySelector('.ons-js-timeout-timer');
10
9
  this.accessibleCountdown = context.querySelector('.ons-js-timeout-timer-acc');
11
10
  this.timeOutRedirectUrl = context.getAttribute('data-redirect-url');
12
- this.modalVisibleInMilliseconds = context.getAttribute('data-show-modal-time') * 1000;
13
11
 
14
12
  // Language dependent text strings
15
13
  this.minutesTextSingular = context.getAttribute('data-minutes-text-singular');
@@ -17,17 +15,15 @@ export default class Timeout {
17
15
  this.secondsTextSingular = context.getAttribute('data-seconds-text-singular');
18
16
  this.secondsTextPlural = context.getAttribute('data-seconds-text-plural');
19
17
  this.countdownText = context.getAttribute('data-countdown-text');
20
- this.redirectingText = context.getAttribute('data-redirecting-text');
18
+ this.countdownExpiredText = context.getAttribute('data-countdown-expired-text');
19
+ this.endWithFullStop = context.getAttribute('data-full-stop');
21
20
 
22
21
  // Settings
23
- this.expiryTimeInMilliseconds = 0;
24
22
  this.expiryTime = '';
25
- this.showModalTimeout = null;
23
+ this.expiryTimeInMilliseconds = 0;
26
24
  this.timers = [];
27
25
  this.timerRunOnce = false;
28
-
29
- // Create modal instance
30
- this.modal = new Modal(this.context);
26
+ this.countdownStarted = false;
31
27
 
32
28
  // Start module
33
29
  this.initialise();
@@ -39,43 +35,31 @@ export default class Timeout {
39
35
  } else {
40
36
  this.expiryTime = await this.setNewExpiryTime();
41
37
  }
42
-
43
38
  this.expiryTimeInMilliseconds = this.convertTimeToMilliSeconds(this.expiryTime);
44
39
 
45
- this.bindEventListeners();
46
- }
47
-
48
- bindEventListeners() {
49
- window.onload = this.startTimeout();
50
- window.addEventListener('focus', this.handleWindowFocus.bind(this));
51
- window.addEventListener('keydown', this.escToClose.bind(this));
52
- this.continueButton.addEventListener('click', this.closeModalAndRestartTimeout.bind(this));
53
- this.addThrottledEvents();
54
- }
55
-
56
- startTimeout() {
57
- clearTimeout(this.showModalTimeout);
58
- this.showModalTimeout = setTimeout(this.openModal.bind(this), this.expiryTimeInMilliseconds - this.modalVisibleInMilliseconds);
59
- }
40
+ if (this.enableTimeoutReset) {
41
+ this.addThrottledResetEvents();
42
+ }
60
43
 
61
- async openModal() {
62
- const modalWillOpen = await this.hasExpiryTimeResetInAnotherTab();
63
- if (modalWillOpen && !this.modal.isDialogOpen()) {
64
- this.modal.openDialog();
44
+ if (this.startOnLoad) {
65
45
  this.startUiCountdown();
66
46
  }
47
+
48
+ window.addEventListener('focus', this.handleWindowFocus.bind(this));
67
49
  }
68
50
 
69
51
  async startUiCountdown() {
70
52
  this.clearTimers();
71
- clearInterval(this.shouldModalCloseCheck);
53
+ this.countdownStarted = true;
72
54
 
73
- this.shouldModalCloseCheck = setInterval(async () => {
74
- await this.hasExpiryTimeResetInAnotherTab();
75
- }, 20000);
55
+ if (this.enableTimeoutReset) {
56
+ this.shouldRestartCheck = setInterval(async () => {
57
+ await this.hasExpiryTimeResetInAnotherTab();
58
+ }, 20000);
59
+ }
76
60
 
77
- let millseconds = this.modalVisibleInMilliseconds;
78
- let seconds = millseconds / 1000;
61
+ let milliseconds = this.convertTimeToMilliSeconds(this.expiryTime);
62
+ let seconds = milliseconds / 1000;
79
63
  let timers = this.timers;
80
64
  let $this = this;
81
65
 
@@ -95,14 +79,15 @@ export default class Timeout {
95
79
  (minutesLeft > 0 ? minutesText : '') +
96
80
  (minutesLeft > 0 && secondsLeft > 0 ? ' ' : '') +
97
81
  (secondsLeft > 0 ? secondsText : '') +
98
- '</span>.';
82
+ '</span>' +
83
+ ($this.endWithFullStop ? '.' : '');
99
84
 
100
85
  if (timerExpired) {
101
- const shouldExpire = await $this.hasExpiryTimeResetInAnotherTab();
86
+ const shouldExpire = this.enableTimeoutReset ? await $this.hasExpiryTimeResetInAnotherTab() : true;
102
87
 
103
88
  if (shouldExpire) {
104
- $this.countdown.innerHTML = '<span class="ons-u-fw-b">' + $this.redirectingText + '</span>';
105
- $this.accessibleCountdown.innerHTML = $this.redirectingText;
89
+ $this.countdown.innerHTML = '<span class="ons-u-fw-b">' + $this.countdownExpiredText + '</span>';
90
+ $this.accessibleCountdown.innerHTML = $this.countdownExpiredText;
106
91
  setTimeout($this.redirect.bind($this), 2000);
107
92
  }
108
93
  } else {
@@ -132,25 +117,16 @@ export default class Timeout {
132
117
  if (checkExpiryTime != this.expiryTime) {
133
118
  this.expiryTime = checkExpiryTime;
134
119
  this.expiryTimeInMilliseconds = this.convertTimeToMilliSeconds(checkExpiryTime);
135
- this.closeModalAndRestartTimeout(this.expiryTimeInMilliseconds);
120
+ this.restartTimeout(this.expiryTimeInMilliseconds);
136
121
  } else {
137
122
  return true;
138
123
  }
139
124
  }
140
125
 
141
- closeModalAndRestartTimeout(timeInMilliSeconds) {
142
- if (typeof timeInMilliSeconds !== 'string') {
143
- timeInMilliSeconds = false;
144
- }
145
- if (this.modal.isDialogOpen()) {
146
- this.modal.closeDialog();
147
- }
148
- this.restartTimeout(timeInMilliSeconds);
149
- }
150
-
151
126
  async restartTimeout(timeInMilliSeconds) {
152
127
  this.clearTimers();
153
- clearInterval(this.shouldModalCloseCheck);
128
+ clearInterval(this.shouldRestartCheck);
129
+ this.countdownStarted = false;
154
130
 
155
131
  if (timeInMilliSeconds) {
156
132
  this.expiryTimeInMilliseconds = timeInMilliSeconds;
@@ -159,26 +135,13 @@ export default class Timeout {
159
135
  this.expiryTime = createNewExpiryTime;
160
136
  this.expiryTimeInMilliseconds = this.convertTimeToMilliSeconds(createNewExpiryTime);
161
137
  }
162
-
163
- this.startTimeout();
164
138
  }
165
139
 
166
140
  async handleWindowFocus() {
167
- if (this.sessionExpiryEndpoint) {
168
- const canSetNewExpiry = await this.setNewExpiryTime();
169
- if (!canSetNewExpiry) {
170
- this.redirect();
171
- } else {
172
- const newExpiryTimeInMilliseconds = this.convertTimeToMilliSeconds(canSetNewExpiry).toString();
173
- this.closeModalAndRestartTimeout(newExpiryTimeInMilliseconds);
174
- }
175
- }
176
- }
177
-
178
- escToClose(event) {
179
- if (this.modal.isDialogOpen() && event.keyCode === 27) {
180
- this.closeModalAndRestartTimeout();
181
- }
141
+ this.expiryTime = await this.getExpiryTime();
142
+ this.clearTimers();
143
+ clearInterval(this.shouldRestartCheck);
144
+ this.startUiCountdown();
182
145
  }
183
146
 
184
147
  async setNewExpiryTime() {
@@ -235,45 +198,45 @@ export default class Timeout {
235
198
  }
236
199
  }
237
200
 
238
- addThrottledEvents() {
201
+ addThrottledResetEvents() {
239
202
  window.onclick = this.throttle(() => {
240
203
  /* istanbul ignore next */
241
- if (!this.modal.isDialogOpen()) {
204
+ if (!this.countdownStarted) {
242
205
  this.restartTimeout();
243
206
  }
244
207
  }, 61000);
245
208
 
246
209
  window.onmousemove = this.throttle(() => {
247
210
  /* istanbul ignore next */
248
- if (!this.modal.isDialogOpen()) {
211
+ if (!this.countdownStarted) {
249
212
  this.restartTimeout();
250
213
  }
251
214
  }, 61000);
252
215
 
253
216
  window.onmousedown = this.throttle(() => {
254
217
  /* istanbul ignore next */
255
- if (!this.modal.isDialogOpen()) {
218
+ if (!this.countdownStarted) {
256
219
  this.restartTimeout();
257
220
  }
258
221
  }, 61000);
259
222
 
260
223
  window.onscroll = this.throttle(() => {
261
224
  /* istanbul ignore next */
262
- if (!this.modal.isDialogOpen()) {
225
+ if (!this.countdownStarted) {
263
226
  this.restartTimeout();
264
227
  }
265
228
  }, 61000);
266
229
 
267
230
  window.onkeypress = this.throttle(() => {
268
231
  /* istanbul ignore next */
269
- if (!this.modal.isDialogOpen()) {
232
+ if (!this.countdownStarted) {
270
233
  this.restartTimeout();
271
234
  }
272
235
  }, 61000);
273
236
 
274
237
  window.onkeyup = this.throttle(() => {
275
238
  /* istanbul ignore next */
276
- if (!this.modal.isDialogOpen()) {
239
+ if (!this.countdownStarted) {
277
240
  this.restartTimeout();
278
241
  }
279
242
  }, 61000);
@@ -18,8 +18,6 @@
18
18
  {% set metaicons = "" %}
19
19
  {% endif %}
20
20
 
21
- {% set pageColNumber = pageConfig.pageColNumber | default("8") %}
22
-
23
21
  {% if pageConfig.cdn is defined and pageConfig.cdn or release_version is defined and release_version %}
24
22
  {# Production #}
25
23
  {% set cdn_url = (pageConfig.cdn.url if pageConfig.cdn is defined and pageConfig.cdn and pageConfig.cdn.url is defined and pageConfig.cdn.url) or "https://cdn.ons.gov.uk/sdc/design-system" %}
@@ -44,6 +42,21 @@
44
42
  {% set page_title = "ONS Design System" %}
45
43
  {% endif %}
46
44
 
45
+ {# Page columns #}
46
+ {% set mainColNumber = "8" %}
47
+
48
+ {% if pageConfig.mainCol is defined and pageConfig.mainCol %}
49
+ {% set mainColNumber = pageConfig.mainCol.columns if pageConfig.mainCol.columns is defined and pageConfig.mainCol.columns %}
50
+ {% set mainColClasses = (' ' + pageConfig.mainCol.colClasses) if pageConfig.mainCol.colClasses is defined and pageConfig.mainCol.colClasses %}
51
+ {% set mainClasses = (' ' + pageConfig.mainCol.classes) if pageConfig.mainCol.classes is defined and pageConfig.mainCol.classes %}
52
+ {% endif %}
53
+
54
+ {% if pageConfig.asideCol is defined and pageConfig.asideCol %}
55
+ {% set asideColNumber = 12 - mainColNumber if pageConfig.asideCol.position is defined and pageConfig.asideCol.position %}
56
+ {% set asideColClasses = (' ' + pageConfig.asideCol.colClasses) if pageConfig.asideCol.colClasses is defined and pageConfig.asideCol.colClasses %}
57
+ {% set asideClasses = (' ' + pageConfig.asideCol.classes) if pageConfig.asideCol.classes is defined and pageConfig.asideCol.classes %}
58
+ {% endif %}
59
+
47
60
  <!doctype html>
48
61
  <html lang="{{ currentLanguageISOCode }}">
49
62
  <head>
@@ -169,11 +182,26 @@
169
182
  {% endif %}
170
183
  {% block preMain %}{% endblock %}
171
184
  <div class="ons-grid">
172
- <div class="ons-grid__col ons-col-{{ pageColNumber }}@m">
173
- <main id="main-content" class="ons-page__main {{ pageClasses }}">
185
+ {% if pageConfig.asideCol is defined and pageConfig.asideCol %}
186
+ {% set aside %}
187
+ <div class="ons-grid__col ons-col-{{ asideColNumber }}@m{{ asideColClasses }}">
188
+ <aside {% if pageConfig.asideCol.id is defined and pageConfig.asideCol.id %}id="{{ asideId }}" {% endif %}class="ons-page__aside{{ asideClasses }}">
189
+ {% block aside %}{% endblock %}
190
+ </aside>
191
+ </div>
192
+ {% endset %}
193
+ {% endif %}
194
+ {% if pageConfig.asideCol.position is defined and pageConfig.asideCol.position == "before" %}
195
+ {{ aside | safe }}
196
+ {% endif %}
197
+ <div class="ons-grid__col ons-col-{{ mainColNumber }}@m{{ mainColClasses }}">
198
+ <main id="main-content" class="ons-page__main{{ mainClasses }}">
174
199
  {% block main %}{% endblock %}
175
200
  </main>
176
201
  </div>
202
+ {% if pageConfig.asideCol.position is defined and pageConfig.asideCol.position == "after" %}
203
+ {{ aside | safe }}
204
+ {% endif %}
177
205
  </div>
178
206
  </div>
179
207
  {% endblock %}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ons/design-system",
3
3
  "description": "ONS Design System built CSS, JS, and Nunjucks templates",
4
- "version": "45.2.1",
4
+ "version": "46.1.0",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
7
7
  "author": {