@govuk-one-login/frontend-ui 3.1.0 → 4.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/build/cjs/frontend/index.cjs +73 -10
- package/build/cjs/frontend/progress-button/progress-button.d.ts +1 -1
- package/build/cjs/frontend/progress-button/progress-button.d.ts.map +1 -1
- package/build/components/bases/mobile/mobile-base.njk +2 -2
- package/build/esm/frontend/index.js +73 -10
- package/build/esm/frontend/progress-button/progress-button.d.ts +1 -1
- package/build/esm/frontend/progress-button/progress-button.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -289,10 +289,23 @@ class Spinner {
|
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
function initialiseProgressButtons() {
|
|
293
|
-
const progressButtons = document.querySelectorAll('[data-frontendui="di-progress-button"]');
|
|
294
|
-
|
|
295
|
-
|
|
292
|
+
function initialiseProgressButtons(document = window.document) {
|
|
293
|
+
const progressButtons = Array.prototype.slice.call(document.querySelectorAll('[data-frontendui="di-progress-button"]'));
|
|
294
|
+
function findClosestForm(element) {
|
|
295
|
+
let el = element;
|
|
296
|
+
while (el && el.nodeName !== 'FORM') {
|
|
297
|
+
el = el.parentElement;
|
|
298
|
+
}
|
|
299
|
+
return el;
|
|
300
|
+
}
|
|
301
|
+
progressButtons.forEach(function (button) {
|
|
302
|
+
const form = findClosestForm(button);
|
|
303
|
+
let isSubmitting = false;
|
|
304
|
+
button.addEventListener('click', function (event) {
|
|
305
|
+
if (isSubmitting) {
|
|
306
|
+
event.preventDefault();
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
296
309
|
const waitingText = button.getAttribute('data-waiting-text');
|
|
297
310
|
const longWaitingText = button.getAttribute('data-long-waiting-text');
|
|
298
311
|
const errorPage = button.getAttribute('data-error-page');
|
|
@@ -301,14 +314,44 @@ function initialiseProgressButtons() {
|
|
|
301
314
|
console.error('Progress button is missing required data attributes.');
|
|
302
315
|
return;
|
|
303
316
|
}
|
|
317
|
+
isSubmitting = true;
|
|
318
|
+
// Always handle the button click, regardless of form presence
|
|
304
319
|
handleProgressButtonClick(button, waitingText, longWaitingText, errorPage, isInput);
|
|
320
|
+
// If no form, we're done. If there is a form, the form submit handler will take over
|
|
321
|
+
if (!form) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
// For form buttons, let the click propagate to trigger form submission
|
|
305
325
|
});
|
|
326
|
+
if (form) {
|
|
327
|
+
form.addEventListener('submit', function (event) {
|
|
328
|
+
// The button click handler has already set isSubmitting and handled the button state
|
|
329
|
+
if (isSubmitting) {
|
|
330
|
+
// Allow the first submission, prevent subsequent ones
|
|
331
|
+
if (event.target === form && event.submitter === button) {
|
|
332
|
+
return; // Allow the first submission to proceed
|
|
333
|
+
}
|
|
334
|
+
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
// If the form is submitted through another method (not our button),
|
|
338
|
+
// prevent double submission but don't show progress state
|
|
339
|
+
isSubmitting = true;
|
|
340
|
+
});
|
|
341
|
+
}
|
|
306
342
|
});
|
|
307
343
|
}
|
|
308
|
-
|
|
309
|
-
element.
|
|
344
|
+
function handleProgressButtonClick(element, waitingText, longWaitingText, errorPage, isInput) {
|
|
345
|
+
var originalText = isInput && element instanceof HTMLInputElement ? element.value : element.innerText;
|
|
346
|
+
if (typeof element.blur === 'function') {
|
|
347
|
+
element.blur();
|
|
348
|
+
}
|
|
310
349
|
element.setAttribute('data-prevent-double-click', 'true');
|
|
311
|
-
element.
|
|
350
|
+
var classes = element.className.split(' ');
|
|
351
|
+
if (classes.indexOf('govuk-button--progress-loading') === -1) {
|
|
352
|
+
classes.push('govuk-button--progress-loading');
|
|
353
|
+
element.className = classes.join(' ');
|
|
354
|
+
}
|
|
312
355
|
if (isInput && element instanceof HTMLInputElement) {
|
|
313
356
|
element.value = waitingText;
|
|
314
357
|
}
|
|
@@ -316,7 +359,7 @@ const handleProgressButtonClick = (element, waitingText, longWaitingText, errorP
|
|
|
316
359
|
element.innerText = waitingText;
|
|
317
360
|
}
|
|
318
361
|
element.setAttribute('aria-label', waitingText);
|
|
319
|
-
setTimeout(()
|
|
362
|
+
var longWaitTimeout = window.setTimeout(function () {
|
|
320
363
|
if (isInput && element instanceof HTMLInputElement) {
|
|
321
364
|
element.value = longWaitingText;
|
|
322
365
|
}
|
|
@@ -325,10 +368,30 @@ const handleProgressButtonClick = (element, waitingText, longWaitingText, errorP
|
|
|
325
368
|
}
|
|
326
369
|
element.setAttribute('aria-label', longWaitingText);
|
|
327
370
|
}, 5000);
|
|
328
|
-
setTimeout(()
|
|
371
|
+
var errorTimeout = window.setTimeout(function () {
|
|
329
372
|
window.location.href = errorPage;
|
|
330
373
|
}, 10000);
|
|
331
|
-
|
|
374
|
+
function resetButton() {
|
|
375
|
+
var classes = element.className.split(' ');
|
|
376
|
+
var loadingIndex = classes.indexOf('govuk-button--progress-loading');
|
|
377
|
+
if (loadingIndex !== -1) {
|
|
378
|
+
classes.splice(loadingIndex, 1);
|
|
379
|
+
element.className = classes.join(' ');
|
|
380
|
+
}
|
|
381
|
+
element.setAttribute('data-prevent-double-click', 'false');
|
|
382
|
+
if (isInput && element instanceof HTMLInputElement) {
|
|
383
|
+
element.value = originalText;
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
element.innerText = originalText;
|
|
387
|
+
}
|
|
388
|
+
element.setAttribute('aria-label', originalText);
|
|
389
|
+
window.clearTimeout(errorTimeout);
|
|
390
|
+
window.clearTimeout(longWaitTimeout);
|
|
391
|
+
}
|
|
392
|
+
element.resetProgressButton = resetButton;
|
|
393
|
+
return resetButton;
|
|
394
|
+
}
|
|
332
395
|
|
|
333
396
|
exports.initialiseProgressButtons = initialiseProgressButtons;
|
|
334
397
|
exports.useSpinner = useSpinner;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function initialiseProgressButtons(): void;
|
|
1
|
+
export declare function initialiseProgressButtons(document?: Document): void;
|
|
2
2
|
//# sourceMappingURL=progress-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress-button.d.ts","sourceRoot":"","sources":["../../../../frontend-src/progress-button/progress-button.ts"],"names":[],"mappings":"AAAA,wBAAgB,yBAAyB,
|
|
1
|
+
{"version":3,"file":"progress-button.d.ts","sourceRoot":"","sources":["../../../../frontend-src/progress-button/progress-button.ts"],"names":[],"mappings":"AAAA,wBAAgB,yBAAyB,CAAC,QAAQ,GAAE,QAA0B,QAgE7E"}
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
translations: {
|
|
101
101
|
footerNavItems: [
|
|
102
102
|
{
|
|
103
|
-
href:
|
|
104
|
-
text: 'general.base.footer.accessibility' | translate
|
|
103
|
+
href: 'general.base.footer.accessibility.link' | translate | safe,
|
|
104
|
+
text: 'general.base.footer.accessibility.linkText' | translate
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
href: 'general.cookieBanner.viewCookiesLink' | translate,
|
|
@@ -287,10 +287,23 @@ class Spinner {
|
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
function initialiseProgressButtons() {
|
|
291
|
-
const progressButtons = document.querySelectorAll('[data-frontendui="di-progress-button"]');
|
|
292
|
-
|
|
293
|
-
|
|
290
|
+
function initialiseProgressButtons(document = window.document) {
|
|
291
|
+
const progressButtons = Array.prototype.slice.call(document.querySelectorAll('[data-frontendui="di-progress-button"]'));
|
|
292
|
+
function findClosestForm(element) {
|
|
293
|
+
let el = element;
|
|
294
|
+
while (el && el.nodeName !== 'FORM') {
|
|
295
|
+
el = el.parentElement;
|
|
296
|
+
}
|
|
297
|
+
return el;
|
|
298
|
+
}
|
|
299
|
+
progressButtons.forEach(function (button) {
|
|
300
|
+
const form = findClosestForm(button);
|
|
301
|
+
let isSubmitting = false;
|
|
302
|
+
button.addEventListener('click', function (event) {
|
|
303
|
+
if (isSubmitting) {
|
|
304
|
+
event.preventDefault();
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
294
307
|
const waitingText = button.getAttribute('data-waiting-text');
|
|
295
308
|
const longWaitingText = button.getAttribute('data-long-waiting-text');
|
|
296
309
|
const errorPage = button.getAttribute('data-error-page');
|
|
@@ -299,14 +312,44 @@ function initialiseProgressButtons() {
|
|
|
299
312
|
console.error('Progress button is missing required data attributes.');
|
|
300
313
|
return;
|
|
301
314
|
}
|
|
315
|
+
isSubmitting = true;
|
|
316
|
+
// Always handle the button click, regardless of form presence
|
|
302
317
|
handleProgressButtonClick(button, waitingText, longWaitingText, errorPage, isInput);
|
|
318
|
+
// If no form, we're done. If there is a form, the form submit handler will take over
|
|
319
|
+
if (!form) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
// For form buttons, let the click propagate to trigger form submission
|
|
303
323
|
});
|
|
324
|
+
if (form) {
|
|
325
|
+
form.addEventListener('submit', function (event) {
|
|
326
|
+
// The button click handler has already set isSubmitting and handled the button state
|
|
327
|
+
if (isSubmitting) {
|
|
328
|
+
// Allow the first submission, prevent subsequent ones
|
|
329
|
+
if (event.target === form && event.submitter === button) {
|
|
330
|
+
return; // Allow the first submission to proceed
|
|
331
|
+
}
|
|
332
|
+
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
// If the form is submitted through another method (not our button),
|
|
336
|
+
// prevent double submission but don't show progress state
|
|
337
|
+
isSubmitting = true;
|
|
338
|
+
});
|
|
339
|
+
}
|
|
304
340
|
});
|
|
305
341
|
}
|
|
306
|
-
|
|
307
|
-
element.
|
|
342
|
+
function handleProgressButtonClick(element, waitingText, longWaitingText, errorPage, isInput) {
|
|
343
|
+
var originalText = isInput && element instanceof HTMLInputElement ? element.value : element.innerText;
|
|
344
|
+
if (typeof element.blur === 'function') {
|
|
345
|
+
element.blur();
|
|
346
|
+
}
|
|
308
347
|
element.setAttribute('data-prevent-double-click', 'true');
|
|
309
|
-
element.
|
|
348
|
+
var classes = element.className.split(' ');
|
|
349
|
+
if (classes.indexOf('govuk-button--progress-loading') === -1) {
|
|
350
|
+
classes.push('govuk-button--progress-loading');
|
|
351
|
+
element.className = classes.join(' ');
|
|
352
|
+
}
|
|
310
353
|
if (isInput && element instanceof HTMLInputElement) {
|
|
311
354
|
element.value = waitingText;
|
|
312
355
|
}
|
|
@@ -314,7 +357,7 @@ const handleProgressButtonClick = (element, waitingText, longWaitingText, errorP
|
|
|
314
357
|
element.innerText = waitingText;
|
|
315
358
|
}
|
|
316
359
|
element.setAttribute('aria-label', waitingText);
|
|
317
|
-
setTimeout(()
|
|
360
|
+
var longWaitTimeout = window.setTimeout(function () {
|
|
318
361
|
if (isInput && element instanceof HTMLInputElement) {
|
|
319
362
|
element.value = longWaitingText;
|
|
320
363
|
}
|
|
@@ -323,9 +366,29 @@ const handleProgressButtonClick = (element, waitingText, longWaitingText, errorP
|
|
|
323
366
|
}
|
|
324
367
|
element.setAttribute('aria-label', longWaitingText);
|
|
325
368
|
}, 5000);
|
|
326
|
-
setTimeout(()
|
|
369
|
+
var errorTimeout = window.setTimeout(function () {
|
|
327
370
|
window.location.href = errorPage;
|
|
328
371
|
}, 10000);
|
|
329
|
-
|
|
372
|
+
function resetButton() {
|
|
373
|
+
var classes = element.className.split(' ');
|
|
374
|
+
var loadingIndex = classes.indexOf('govuk-button--progress-loading');
|
|
375
|
+
if (loadingIndex !== -1) {
|
|
376
|
+
classes.splice(loadingIndex, 1);
|
|
377
|
+
element.className = classes.join(' ');
|
|
378
|
+
}
|
|
379
|
+
element.setAttribute('data-prevent-double-click', 'false');
|
|
380
|
+
if (isInput && element instanceof HTMLInputElement) {
|
|
381
|
+
element.value = originalText;
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
element.innerText = originalText;
|
|
385
|
+
}
|
|
386
|
+
element.setAttribute('aria-label', originalText);
|
|
387
|
+
window.clearTimeout(errorTimeout);
|
|
388
|
+
window.clearTimeout(longWaitTimeout);
|
|
389
|
+
}
|
|
390
|
+
element.resetProgressButton = resetButton;
|
|
391
|
+
return resetButton;
|
|
392
|
+
}
|
|
330
393
|
|
|
331
394
|
export { PollResult, initialiseProgressButtons, useSpinner };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function initialiseProgressButtons(): void;
|
|
1
|
+
export declare function initialiseProgressButtons(document?: Document): void;
|
|
2
2
|
//# sourceMappingURL=progress-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress-button.d.ts","sourceRoot":"","sources":["../../../../frontend-src/progress-button/progress-button.ts"],"names":[],"mappings":"AAAA,wBAAgB,yBAAyB,
|
|
1
|
+
{"version":3,"file":"progress-button.d.ts","sourceRoot":"","sources":["../../../../frontend-src/progress-button/progress-button.ts"],"names":[],"mappings":"AAAA,wBAAgB,yBAAyB,CAAC,QAAQ,GAAE,QAA0B,QAgE7E"}
|