@govuk-one-login/frontend-ui 1.4.3 → 2.0.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.
package/README.md CHANGED
@@ -152,4 +152,21 @@ or
152
152
 
153
153
  {% extends "frontend-ui/build/components/bases/identity/identity-base-page.njk" %}
154
154
 
155
- ```
155
+ ```
156
+
157
+ ### 8. Import frontend JS
158
+
159
+ If you need to use a component that incorporates frontend (ie. in-browser) code then you will also need to include the frontend javascript bundle by either importing it in to you existing frontend bundling solution if you use one, or copying and exposing the esm version (`@govuk-one-login/frontend-ui/build/esm/frontend/index.js`) in your public folder. Then add the script tag on to any page where you use it.
160
+
161
+ ```html
162
+ <script nonce='{{ cspNonce }}' defer type="module" src="/public/javascripts/frontend-ui.js"></script>
163
+ <script nonce='{{ cspNonce }}' defer type="module">
164
+ import { useSpinner } from "/public/javascripts/frontend-ui.js";
165
+ useSpinner();
166
+ </script>
167
+ ```
168
+
169
+ # Upgrading to V2
170
+
171
+ ## On Page Load has now been added to basefiles
172
+ When upgrading to major version 2, GA4 on page load will be within the idenity and core basefiles, this will be a breaking change and implement some duplication on pages if GA4OPL is already being used on them
@@ -1,251 +1,314 @@
1
1
  'use strict';
2
2
 
3
- const WaitInteractions = (() => {
4
- var _a;
5
- const content = {
6
- initial: {
7
- spinnerState: "pending",
8
- },
9
- complete: { spinnerState: "completed" },
10
- };
11
- const state = {
12
- spinnerState: (_a = content === null || content === void 0 ? void 0 : content.initial) === null || _a === void 0 ? void 0 : _a.spinnerState,
13
- done: false,
14
- virtualDom: [],
15
- abortController: null,
16
- };
17
- const timers = {};
18
- let { container, ariaLiveContainer, domRequirementsMet, initTime, abortController, config, } = {
19
- };
20
- const handleAbort = () => {
21
- abortController === null || abortController === void 0 ? void 0 : abortController.abort();
22
- };
23
- const initialiseAbortController = () => {
24
- abortController = new AbortController();
25
- window.removeEventListener("beforeunload", handleAbort);
26
- window.addEventListener("beforeunload", handleAbort);
27
- };
28
- const updateAccordingToTimeElapsed = () => {
29
- const now = Date.now();
30
- const elapsedMilliseconds = now - initTime;
31
- if (elapsedMilliseconds >= config.msBeforeAbort) {
32
- reflectError();
3
+ function useSpinner() {
4
+ const element = document.getElementById("spinner-container");
5
+ if (element) {
6
+ const spinner = new Spinner(element);
7
+ spinner.init();
8
+ }
9
+ else {
10
+ console.warn("Attempting to initiate a spinner on a page with no '#spinner-container' element.");
11
+ }
12
+ }
13
+ class Spinner {
14
+ reflectLongWait() {
15
+ if (this.state.spinnerState !== "ready") {
16
+ this.state.spinnerStateText = this.content.longWait.spinnerStateText;
17
+ }
18
+ }
19
+ initialiseState() {
20
+ if (this.domRequirementsMet) {
21
+ this.state = {
22
+ heading: this.content.initial.heading,
23
+ spinnerStateText: this.content.initial.spinnerStateText,
24
+ spinnerState: this.content.initial.spinnerState,
25
+ buttonDisabled: true,
26
+ ariaButtonEnabledMessage: "",
27
+ done: false,
28
+ error: false,
29
+ virtualDom: [],
30
+ };
31
+ }
32
+ }
33
+ initialiseContent(element) {
34
+ var _a;
35
+ function throwIfMissing(data) {
36
+ if (data === undefined || data === null) {
37
+ throw new Error("Missing required data");
38
+ }
39
+ return data;
40
+ }
41
+ try {
42
+ this.content = {
43
+ initial: {
44
+ heading: throwIfMissing(element.dataset.initialHeading),
45
+ spinnerStateText: throwIfMissing(element.dataset.initialSpinnerstatetext),
46
+ spinnerState: throwIfMissing(element.dataset.initialSpinnerstate),
47
+ },
48
+ error: {
49
+ heading: throwIfMissing(element.dataset.errorHeading),
50
+ messageText: throwIfMissing(element.dataset.errorMessagetext),
51
+ whatYouCanDo: {
52
+ heading: throwIfMissing(element.dataset.errorWhatyoucandoHeading),
53
+ message: {
54
+ text1: throwIfMissing(element.dataset.errorWhatyoucandoMessageText1),
55
+ link: {
56
+ href: throwIfMissing(element.dataset.errorWhatyoucandoMessageLinkHref),
57
+ text: throwIfMissing(element.dataset.errorWhatyoucandoMessageLinkText),
58
+ },
59
+ text2: throwIfMissing(element.dataset.errorWhatyoucandoMessageText2),
60
+ },
61
+ },
62
+ },
63
+ complete: {
64
+ spinnerState: throwIfMissing(element.dataset.completeSpinnerstate),
65
+ },
66
+ longWait: {
67
+ spinnerStateText: throwIfMissing(element.dataset.longwaitSpinnerstatetext),
68
+ },
69
+ continueButton: {
70
+ text: (_a = element.dataset.continuebuttonText) !== null && _a !== void 0 ? _a : "Continue",
71
+ },
72
+ };
73
+ this.config = {
74
+ apiUrl: element.dataset.apiUrl || this.config.apiUrl,
75
+ ariaButtonEnabledMessage: throwIfMissing(element.dataset.ariaButtonEnabledMessage),
76
+ msBeforeInformingOfLongWait: element.dataset.msBeforeInformingOfLongWait
77
+ ? parseInt(element.dataset.msBeforeInformingOfLongWait)
78
+ : this.config.msBeforeInformingOfLongWait,
79
+ msBeforeAbort: element.dataset.msBeforeAbort
80
+ ? parseInt(element.dataset.msBeforeAbort)
81
+ : this.config.msBeforeAbort,
82
+ msBetweenRequests: element.dataset.msBetweenRequests
83
+ ? parseInt(element.dataset.msBetweenRequests)
84
+ : this.config.msBetweenRequests,
85
+ msBetweenDomUpdate: element.dataset.msBetweenDomUpdate
86
+ ? parseInt(element.dataset.msBetweenDomUpdate)
87
+ : this.config.msBetweenDomUpdate,
88
+ };
89
+ this.domRequirementsMet = true;
33
90
  }
34
- else if ((elapsedMilliseconds >=
35
- config.msBeforeInformingOfLongWait)) {
36
- reflectLongWait();
91
+ catch (e) {
92
+ this.domRequirementsMet = false;
37
93
  }
38
- };
39
- const createVirtualDom = () => {
40
- var _a, _b, _c, _d, _e, _f;
41
- const initialState = [
94
+ }
95
+ createVirtualDom() {
96
+ const domInitialState = [
42
97
  {
43
98
  nodeName: "h1",
44
- text: state.heading,
99
+ text: this.state.heading,
45
100
  classes: ["govuk-heading-l"],
46
101
  },
47
102
  {
48
103
  nodeName: "div",
49
104
  id: "spinner",
50
- classes: ["spinner", "spinner__pending", "centre", state.spinnerState],
105
+ classes: [
106
+ "spinner",
107
+ "spinner__pending",
108
+ "centre",
109
+ this.state.spinnerState,
110
+ ],
51
111
  },
52
112
  {
53
113
  nodeName: "p",
54
- text: state.spinnerStateText,
114
+ text: this.state.spinnerStateText,
55
115
  classes: ["centre", "spinner-state-text", "govuk-body"],
56
116
  },
57
117
  {
58
118
  nodeName: "button",
59
- text: (_a = content === null || content === void 0 ? void 0 : content.continueButton) === null || _a === void 0 ? void 0 : _a.text,
60
- buttonDisabled: state.buttonDisabled,
119
+ text: this.content.continueButton.text,
120
+ buttonDisabled: this.state.buttonDisabled,
61
121
  classes: ["govuk-button", "govuk-!-margin-top-4"],
62
122
  },
63
123
  ];
64
124
  const domErrorState = [
65
125
  {
66
126
  nodeName: "h1",
67
- text: state.heading,
127
+ text: this.state.heading,
68
128
  classes: ["govuk-heading-l"],
69
129
  },
70
130
  {
71
131
  nodeName: "p",
72
- text: state.messageText,
132
+ text: this.state.messageText,
73
133
  classes: ["govuk-body"],
74
134
  },
75
135
  {
76
136
  nodeName: "h2",
77
- text: (_b = content === null || content === void 0 ? void 0 : content.error) === null || _b === void 0 ? void 0 : _b.whatYouCanDo.heading,
137
+ text: this.content.error.whatYouCanDo.heading,
78
138
  classes: ["govuk-heading-m"],
79
139
  },
80
140
  {
81
141
  nodeName: "p",
82
- innerHTML: `${(_c = content === null || content === void 0 ? void 0 : content.error) === null || _c === void 0 ? void 0 : _c.whatYouCanDo.message.text1}<a href="${(_d = content === null || content === void 0 ? void 0 : content.error) === null || _d === void 0 ? void 0 : _d.whatYouCanDo.message.link.href}">${(_e = content === null || content === void 0 ? void 0 : content.error) === null || _e === void 0 ? void 0 : _e.whatYouCanDo.message.link.text}</a>${(_f = content === null || content === void 0 ? void 0 : content.error) === null || _f === void 0 ? void 0 : _f.whatYouCanDo.message.text2}`,
142
+ innerHTML: `${this.content.error.whatYouCanDo.message.text1}<a href="${this.content.error.whatYouCanDo.message.link.href}">${this.content.error.whatYouCanDo.message.link.text}</a>${this.content.error.whatYouCanDo.message.text2}`,
83
143
  classes: ["govuk-body"],
84
144
  },
85
145
  ];
86
- return state.error ? domErrorState : initialState;
87
- };
88
- const vDomHasChanged = (currentVDom, nextVDom) => {
89
- return JSON.stringify(currentVDom) !== JSON.stringify(nextVDom);
90
- };
91
- const updateDom = () => {
92
- var _a;
93
- const vDomChanged = vDomHasChanged(state.virtualDom, createVirtualDom());
94
- const container = document.getElementById("spinner-container");
95
- if (vDomChanged) {
96
- document.title = state.heading;
97
- state.virtualDom = createVirtualDom();
98
- const elements = (_a = state === null || state === void 0 ? void 0 : state.virtualDom) === null || _a === void 0 ? void 0 : _a.map(convert);
99
- container === null || container === void 0 ? void 0 : container.replaceChildren(...elements);
100
- }
101
- if (state.error) {
102
- container === null || container === void 0 ? void 0 : container.classList.add("spinner-container__error");
103
- }
104
- if (state.done) {
105
- clearInterval(timers.updateDomTimer);
106
- }
107
- if (state.ariaButtonEnabledMessage !== "") {
108
- updateAriaAlert(config === null || config === void 0 ? void 0 : config.ariaButtonEnabledMessage);
109
- }
110
- };
111
- const reflectCompletion = () => {
112
- var _a, _b;
113
- state.spinnerState = "spinner__ready";
114
- state.spinnerStateText = (_a = content === null || content === void 0 ? void 0 : content.complete) === null || _a === void 0 ? void 0 : _a.spinnerState;
115
- state.buttonDisabled = false;
116
- state.ariaButtonEnabledMessage =
117
- (_b = content === null || content === void 0 ? void 0 : content.complete) === null || _b === void 0 ? void 0 : _b.ariaButtonEnabledMessage;
118
- state.done = true;
119
- sessionStorage.removeItem("spinnerInitTime");
120
- };
121
- const reflectError = () => {
122
- var _a, _b, _c;
123
- state.heading = (_a = content === null || content === void 0 ? void 0 : content.error) === null || _a === void 0 ? void 0 : _a.heading;
124
- state.messageText = (_b = content === null || content === void 0 ? void 0 : content.error) === null || _b === void 0 ? void 0 : _b.messageText;
125
- state.spinnerState = "spinner__failed";
126
- state.done = true;
127
- state.error = true;
128
- sessionStorage.removeItem("spinnerInitTime");
129
- (_c = state === null || state === void 0 ? void 0 : state.abortController) === null || _c === void 0 ? void 0 : _c.abort();
130
- };
131
- const reflectLongWait = () => {
132
- var _a;
133
- if (state.spinnerState !== "ready") {
134
- state.spinnerStateText = (_a = content === null || content === void 0 ? void 0 : content.longWait) === null || _a === void 0 ? void 0 : _a.spinnerStateText;
135
- }
136
- };
137
- const convert = (node) => {
138
- const el = document.createElement(node.nodeName);
139
- if (node.text)
140
- el.textContent = node.text;
141
- if (node.innerHTML)
142
- el.innerHTML = node.innerHTML;
143
- if (node.id)
144
- el.id = node.id;
145
- if (node.classes)
146
- el.classList.add(...node.classes);
147
- if (node.buttonDisabled)
148
- el.setAttribute("disabled", node.buttonDisabled);
149
- return el;
150
- };
151
- const updateAriaAlert = (messageText) => {
152
- while (ariaLiveContainer === null || ariaLiveContainer === void 0 ? void 0 : ariaLiveContainer.firstChild) {
153
- ariaLiveContainer.removeChild(ariaLiveContainer.firstChild);
154
- }
155
- /* Create new message and append it to the live region */
156
- const messageNode = document.createTextNode(messageText);
157
- ariaLiveContainer === null || ariaLiveContainer === void 0 ? void 0 : ariaLiveContainer.appendChild(messageNode);
158
- };
159
- const notInErrorOrDoneState = () => {
160
- return !(state.done || state.error);
161
- };
162
- const requestIDProcessingStatus = async () => {
163
- var _a;
164
- const signal = abortController.signal;
165
- const apiRoute = (_a = document === null || document === void 0 ? void 0 : document.getElementById("spinner-container")) === null || _a === void 0 ? void 0 : _a.dataset.apiRoute;
166
- try {
167
- const response = await fetch(apiRoute, { signal });
168
- if (response.status !== 200) {
169
- throw new Error(`Status code ${response.status} received`);
170
- }
171
- const data = await response.json();
172
- if (data.status === "COMPLETED" ||
173
- data.status === "INTERVENTION") {
174
- reflectCompletion();
146
+ return this.state.error ? domErrorState : domInitialState;
147
+ }
148
+ async requestIDProcessingStatus(initTime) {
149
+ const signal = this.abortController.signal;
150
+ await fetch(this.config.apiUrl, { signal })
151
+ .then((response) => response.json())
152
+ .then((data) => {
153
+ if (data.status === "COMPLETED" || data.status === "INTERVENTION") {
154
+ this.reflectCompletion();
175
155
  }
176
156
  else if (data.status === "ERROR") {
177
- reflectError();
157
+ this.reflectError();
178
158
  }
179
- else if (notInErrorOrDoneState()) {
159
+ else if (this.notInErrorOrDoneState()) {
180
160
  setTimeout(async () => {
181
- if (Date.now() - initTime >= config.msBeforeAbort) {
161
+ if (Date.now() - initTime >= this.config.msBeforeAbort) {
182
162
  return;
183
163
  }
184
- await requestIDProcessingStatus();
185
- }, config.msBetweenRequests);
186
- }
187
- if (data.status === "Clear to proceed") {
188
- reflectCompletion();
164
+ await this.requestIDProcessingStatus(initTime);
165
+ }, this.config.msBetweenRequests);
189
166
  }
190
- else if (notInErrorOrDoneState()) {
191
- setTimeout(async () => {
192
- await requestIDProcessingStatus();
193
- }, 1000);
167
+ })
168
+ .catch((error) => {
169
+ if (error.name !== "AbortError") {
170
+ console.error("Error in requestIDProcessingStatus:", error);
171
+ this.reflectError();
194
172
  }
195
- }
196
- catch (e) {
197
- console.log(e);
198
- reflectError();
199
- if (e.name !== "AbortError") {
200
- console.error("Error in requestIdProcessingStatus:", e);
201
- reflectError();
202
- }
203
- }
204
- };
205
- const initTimer = () => {
206
- let spinnerInitTime = sessionStorage.getItem("spinnerInitTime");
207
- if (spinnerInitTime === null) {
173
+ })
174
+ .finally(() => {
175
+ this.updateDom();
176
+ });
177
+ }
178
+ getInitTime() {
179
+ const storedSpinnerInitTime = sessionStorage.getItem("spinnerInitTime");
180
+ let spinnerInitTime;
181
+ if (storedSpinnerInitTime === null) {
208
182
  spinnerInitTime = Date.now();
209
183
  sessionStorage.setItem("spinnerInitTime", spinnerInitTime.toString());
210
184
  }
211
185
  else {
212
- spinnerInitTime = parseInt(spinnerInitTime, 10);
186
+ spinnerInitTime = parseInt(storedSpinnerInitTime, 10);
187
+ }
188
+ return spinnerInitTime;
189
+ }
190
+ init() {
191
+ if (this.domRequirementsMet) {
192
+ const initTime = this.getInitTime();
193
+ this.initTimer(initTime);
194
+ this.initialiseContainers();
195
+ this.updateDom();
196
+ this.requestIDProcessingStatus(initTime);
213
197
  }
214
- initTime = spinnerInitTime;
215
- updateAccordingToTimeElapsed();
216
- setInterval(() => {
217
- updateAccordingToTimeElapsed();
218
- updateDom();
219
- }, config === null || config === void 0 ? void 0 : config.msBetweenDomUpdate);
220
- };
221
- const initialiseContainers = () => {
222
- const spinnerContainer = document.createElement("div");
223
- const ariaLiveContainer = document.createElement("div");
224
- ariaLiveContainer.setAttribute("aria-live", "assertive");
225
- ariaLiveContainer.classList.add("govuk-visually-hidden");
226
- ariaLiveContainer.appendChild(document.createTextNode(""));
227
- container === null || container === void 0 ? void 0 : container.replaceChildren(spinnerContainer, ariaLiveContainer);
228
- };
229
- return {
230
- state: state,
231
- init: () => {
232
- timers.updateDomTimer = setInterval(updateDom, 2000);
233
- timers.abortUnresponsiveRequest = setTimeout(() => {
234
- reflectError();
235
- }, 15000);
236
- updateDom();
237
- requestIDProcessingStatus().then(() => {
238
- updateDom();
239
- });
240
- if (domRequirementsMet) {
241
- initTimer();
242
- initialiseContainers();
243
- initialiseAbortController();
244
- updateDom();
245
- requestIDProcessingStatus();
198
+ }
199
+ constructor(domContainer) {
200
+ this.config = {
201
+ apiUrl: "/prove-identity-status",
202
+ msBeforeInformingOfLongWait: 5000,
203
+ msBeforeAbort: 25000,
204
+ msBetweenRequests: 1000,
205
+ msBetweenDomUpdate: 2000,
206
+ };
207
+ this.notInErrorOrDoneState = () => {
208
+ return !(this.state.done || this.state.error);
209
+ };
210
+ this.reflectCompletion = () => {
211
+ this.state.spinnerState = "spinner__ready";
212
+ this.state.spinnerStateText = this.content.complete.spinnerState;
213
+ this.state.buttonDisabled = false;
214
+ this.state.ariaButtonEnabledMessage =
215
+ this.content.complete.ariaButtonEnabledMessage;
216
+ this.state.done = true;
217
+ sessionStorage.removeItem("spinnerInitTime");
218
+ };
219
+ this.reflectError = () => {
220
+ this.state.heading = this.content.error.heading;
221
+ this.state.messageText = this.content.error.messageText;
222
+ this.state.spinnerState = "spinner__failed";
223
+ this.state.done = true;
224
+ this.state.error = true;
225
+ sessionStorage.removeItem("spinnerInitTime");
226
+ this.abortController.abort();
227
+ };
228
+ this.updateAccordingToTimeElapsed = (initTime) => {
229
+ const elapsedMilliseconds = Date.now() - initTime;
230
+ if (elapsedMilliseconds >= this.config.msBeforeAbort) {
231
+ this.reflectError();
232
+ }
233
+ else if (elapsedMilliseconds >= this.config.msBeforeInformingOfLongWait) {
234
+ this.reflectLongWait();
235
+ }
236
+ };
237
+ this.vDomHasChanged = (currentVDom, nextVDom) => {
238
+ return JSON.stringify(currentVDom) !== JSON.stringify(nextVDom);
239
+ };
240
+ this.convert = (node) => {
241
+ const el = document.createElement(node.nodeName);
242
+ if (node.text)
243
+ el.textContent = node.text;
244
+ if (node.innerHTML)
245
+ el.innerHTML = node.innerHTML;
246
+ if (node.id)
247
+ el.id = node.id;
248
+ if (node.classes)
249
+ el.classList.add(...node.classes);
250
+ if (node.buttonDisabled)
251
+ el.setAttribute("disabled", `${node.buttonDisabled}`);
252
+ return el;
253
+ };
254
+ this.updateAriaAlert = (messageText) => {
255
+ while (this.ariaLiveContainer.firstChild) {
256
+ this.ariaLiveContainer.removeChild(this.ariaLiveContainer.firstChild);
257
+ }
258
+ /* Create new message and append it to the live region */
259
+ const messageNode = document.createTextNode(messageText);
260
+ this.ariaLiveContainer.appendChild(messageNode);
261
+ };
262
+ this.updateDom = () => {
263
+ const vDomChanged = this.vDomHasChanged(this.state.virtualDom, this.createVirtualDom());
264
+ if (vDomChanged) {
265
+ document.title = this.state.heading;
266
+ this.state.virtualDom = this.createVirtualDom();
267
+ const elements = this.state.virtualDom.map(this.convert);
268
+ this.spinnerContainer.replaceChildren(...elements);
269
+ }
270
+ if (this.state.error) {
271
+ this.spinnerContainer.classList.add("spinner-container__error");
272
+ }
273
+ if (this.state.done) {
274
+ clearInterval(this.updateDomTimer);
275
+ }
276
+ if (this.config.ariaButtonEnabledMessage &&
277
+ this.state.ariaButtonEnabledMessage !== "") {
278
+ this.updateAriaAlert(this.config.ariaButtonEnabledMessage);
246
279
  }
247
- },
248
- };
249
- })();
280
+ };
281
+ // For the Aria alert to work reliably we need to create its container once and then update the contents
282
+ // https://tetralogical.com/blog/2024/05/01/why-are-my-live-regions-not-working/
283
+ // So here we create a separate DOM element for the Aria live text that won't be touched when the spinner updates.
284
+ this.initialiseContainers = () => {
285
+ this.spinnerContainer = document.createElement("div");
286
+ this.ariaLiveContainer = document.createElement("div");
287
+ this.ariaLiveContainer.setAttribute("aria-live", "assertive");
288
+ this.ariaLiveContainer.classList.add("govuk-visually-hidden");
289
+ this.ariaLiveContainer.appendChild(document.createTextNode(""));
290
+ this.container.replaceChildren(this.spinnerContainer, this.ariaLiveContainer);
291
+ };
292
+ this.initTimer = (initTime) => {
293
+ this.updateAccordingToTimeElapsed(initTime);
294
+ this.updateDomTimer = setInterval(() => {
295
+ this.updateAccordingToTimeElapsed(initTime);
296
+ this.updateDom();
297
+ }, this.config.msBetweenDomUpdate);
298
+ };
299
+ this.handleAbort = () => {
300
+ this.abortController.abort();
301
+ };
302
+ this.initialiseAbortController = () => {
303
+ this.abortController = new AbortController();
304
+ window.removeEventListener("beforeunload", this.handleAbort);
305
+ window.addEventListener("beforeunload", this.handleAbort);
306
+ };
307
+ this.container = domContainer;
308
+ this.initialiseContent(this.container);
309
+ this.initialiseState();
310
+ this.initialiseAbortController();
311
+ }
312
+ }
250
313
 
251
- exports.WaitInteractions = WaitInteractions;
314
+ exports.useSpinner = useSpinner;
@@ -1,2 +1,2 @@
1
- export { WaitInteractions } from "./typescript/spinner";
1
+ export { useSpinner } from "./spinner/spinner";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1,2 @@
1
- export { WaitInteractions } from "./typescript/spinner";
1
+ export { useSpinner } from "./spinner/spinner";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../frontend-src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../frontend-src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function wait(ms: number): Promise<unknown>;
2
+ export declare function waitUntil(conditionFn: Function, { timeout, interval }?: {
3
+ timeout?: number | undefined;
4
+ interval?: number | undefined;
5
+ }): Promise<void>;
6
+ //# sourceMappingURL=spinner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.test.d.ts","sourceRoot":"","sources":["../../../../../frontend-src/spinner/__tests__/spinner.test.ts"],"names":[],"mappings":"AAEA,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,oBAE9B;AAED,wBAAsB,SAAS,CAC7B,WAAW,EAAE,QAAQ,EACrB,EAAE,OAAc,EAAE,QAAa,EAAE;;;CAAK,iBAcvC"}
@@ -0,0 +1,90 @@
1
+ export declare function useSpinner(): void;
2
+ type TVDOM = {
3
+ classes: string[];
4
+ buttonDisabled?: boolean;
5
+ id?: string;
6
+ innerHTML?: string;
7
+ nodeName: string;
8
+ text?: string;
9
+ };
10
+ export declare class Spinner {
11
+ container: HTMLElement;
12
+ spinnerContainer: HTMLElement;
13
+ ariaLiveContainer: HTMLElement;
14
+ content: {
15
+ complete: {
16
+ ariaButtonEnabledMessage?: string;
17
+ spinnerState: string;
18
+ };
19
+ continueButton: {
20
+ text: string;
21
+ };
22
+ error: {
23
+ heading: string;
24
+ messageText: string;
25
+ whatYouCanDo: {
26
+ heading: string;
27
+ message: {
28
+ text1: string;
29
+ link: {
30
+ href: string;
31
+ text: string;
32
+ };
33
+ text2: string;
34
+ };
35
+ };
36
+ };
37
+ initial: {
38
+ heading: string;
39
+ spinnerStateText: string;
40
+ spinnerState: string;
41
+ };
42
+ longWait: {
43
+ spinnerStateText: string;
44
+ };
45
+ };
46
+ domRequirementsMet?: boolean;
47
+ state: {
48
+ ariaButtonEnabledMessage?: string;
49
+ buttonDisabled: boolean;
50
+ done: boolean;
51
+ error: boolean;
52
+ heading: string;
53
+ messageText?: string;
54
+ spinnerState: string;
55
+ spinnerStateText: string;
56
+ virtualDom: TVDOM[];
57
+ };
58
+ updateDomTimer: NodeJS.Timeout;
59
+ abortController: AbortController;
60
+ config: {
61
+ apiUrl: string;
62
+ ariaButtonEnabledMessage?: string;
63
+ msBeforeInformingOfLongWait: number;
64
+ msBeforeAbort: number;
65
+ msBetweenRequests: number;
66
+ msBetweenDomUpdate: number;
67
+ };
68
+ notInErrorOrDoneState: () => boolean;
69
+ reflectCompletion: () => void;
70
+ reflectError: () => void;
71
+ reflectLongWait(): void;
72
+ updateAccordingToTimeElapsed: (initTime: number) => void;
73
+ initialiseState(): void;
74
+ initialiseContent(element: HTMLElement): void;
75
+ createVirtualDom(): TVDOM[];
76
+ vDomHasChanged: (currentVDom: TVDOM[], nextVDom: TVDOM[]) => boolean;
77
+ convert: (node: TVDOM) => HTMLElement;
78
+ updateAriaAlert: (messageText: string) => void;
79
+ updateDom: () => void;
80
+ requestIDProcessingStatus(initTime: number): Promise<void>;
81
+ initialiseContainers: () => void;
82
+ getInitTime(): number;
83
+ initTimer: (initTime: number) => void;
84
+ handleAbort: () => void;
85
+ initialiseAbortController: () => void;
86
+ init(): void;
87
+ constructor(domContainer: HTMLElement);
88
+ }
89
+ export {};
90
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../../../frontend-src/spinner/spinner.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,SAWzB;AAED,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,OAAO;IAClB,SAAS,cAAC;IACV,gBAAgB,EAAE,WAAW,CAAC;IAC9B,iBAAiB,EAAE,WAAW,CAAC;IAC/B,OAAO,EAAE;QACP,QAAQ,EAAE;YACR,wBAAwB,CAAC,EAAE,MAAM,CAAC;YAClC,YAAY,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,cAAc,EAAE;YACd,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;QACF,KAAK,EAAE;YACL,OAAO,EAAE,MAAM,CAAC;YAChB,WAAW,EAAE,MAAM,CAAC;YACpB,YAAY,EAAE;gBACZ,OAAO,EAAE,MAAM,CAAC;gBAChB,OAAO,EAAE;oBACP,KAAK,EAAE,MAAM,CAAC;oBACd,IAAI,EAAE;wBACJ,IAAI,EAAE,MAAM,CAAC;wBACb,IAAI,EAAE,MAAM,CAAC;qBACd,CAAC;oBACF,KAAK,EAAE,MAAM,CAAC;iBACf,CAAC;aACH,CAAC;SACH,CAAC;QACF,OAAO,EAAE;YACP,OAAO,EAAE,MAAM,CAAC;YAChB,gBAAgB,EAAE,MAAM,CAAC;YACzB,YAAY,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,QAAQ,EAAE;YACR,gBAAgB,EAAE,MAAM,CAAC;SAC1B,CAAC;KACH,CAAC;IACF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE;QACL,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,cAAc,EAAE,OAAO,CAAC;QACxB,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,UAAU,EAAE,KAAK,EAAE,CAAC;KACrB,CAAC;IACF,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,2BAA2B,EAAE,MAAM,CAAC;QACpC,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAMC;IAEF,qBAAqB,gBAEnB;IAEF,iBAAiB,aAQf;IAEF,YAAY,aAQV;IAEF,eAAe;IAMf,4BAA4B,GAAI,UAAU,MAAM,UAO9C;IAEF,eAAe;IAef,iBAAiB,CAAC,OAAO,EAAE,WAAW;IA8EtC,gBAAgB,IAAI,KAAK,EAAE;IAwD3B,cAAc,GAAI,aAAa,KAAK,EAAE,EAAE,UAAU,KAAK,EAAE,aAEvD;IAEF,OAAO,GAAI,MAAM,KAAK,iBASpB;IAEF,eAAe,GAAI,aAAa,MAAM,UAQpC;IAEF,SAAS,aA0BP;IAEI,yBAAyB,CAAC,QAAQ,EAAE,MAAM;IAgChD,oBAAoB,aAUlB;IAEF,WAAW;IAYX,SAAS,GAAI,UAAU,MAAM,UAO3B;IAEF,WAAW,aAET;IAEF,yBAAyB,aAIvB;IAEF,IAAI;gBAWQ,YAAY,EAAE,WAAW;CAMtC"}