@govuk-one-login/frontend-ui 4.0.1 → 4.1.1

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/all.css CHANGED
@@ -1 +1 @@
1
- @media(max-width: 640px){.govuk-header__navigation-item{border-left:none !important}.govuk-template--rebranded .govuk-header__navigation-list{padding-bottom:0px !important}.govuk-header__navigation-item{padding-top:8px !important}}.frontendUi_header_signOut-item{padding:5px 0px 5px 30px;border-left:1px solid #b1b4b6;margin-left:auto}.frontendUi_header_signOut-item--rebrand{border-left:none;padding:5px 0px 5px 0px;margin-left:auto;font-weight:700 !important}.frontendUi_header__signOut{display:flex;flex-wrap:wrap}.frontendUi-header__content{margin-left:auto}.govuk-header__navigation--signOut{padding:15px 0 15px !important}.govuk-template--rebranded .govuk-header__navigation{padding:15px 0 15px !important}@media(max-width: 640px){.govuk-header__navigation--signOut{padding:18px 0 8px !important}.govuk-template--rebranded .govuk-header__navigation{padding:18px 0 8px !important}}.govuk-template--rebranded .govuk-header__navigation-item a{font-weight:700 !important}.govuk-template--rebranded .govuk-header__navigation-item{padding-top:5px !important}@media(min-width: 20em)and (max-width: 48.0525em){.govuk-template--rebranded .govuk-header__navigation-list{padding-bottom:0px}}@media(max-width: 323px){.govuk-header__logo{padding-right:5px}.frontendUi_header_signOut-item{padding-left:0px}}@media(max-width: 261px){.frontendUi-header__content{margin-left:unset}.govuk-template--rebranded .govuk-header__navigation{padding:0px 0 8px !important}.govuk-header__logotype{max-width:100%;max-height:auto}.govuk-template--rebranded .govuk-header__logo{padding-top:5% !important;padding-bottom:5% !important}}.govuk-tag{font-size:16px;font-weight:bold;line-height:1;display:inline-block;padding-top:5px;padding-right:8px;padding-bottom:4px;padding-left:8px;outline:2px solid rgba(0,0,0,0);outline-offset:-2px;color:#fff !important;background-color:#1d70b8 !important;letter-spacing:1px !important;text-decoration:none !important;text-transform:uppercase !important}@media(max-width: 256px){.govuk-phase-banner__content{display:block}}.language-select{margin:15px 0 15px 0}.language-select__list{margin-top:1em;text-align:right}.language-select__list-item{display:inline-block}.language-select__list-item:first-child::after{content:"";display:inline-block;position:relative;top:.1875em;height:1em;border-right:.09375em solid #000}.language-select__list-item a,.language-select__list-item [aria-current]{padding:.3125em}@media screen and (max-width: 641px){.language-select__list{float:none;text-align:left;padding-bottom:10px;border-bottom:1px solid #b1b4b6}}.spinner{width:80px;height:80px;border-radius:50%;border-width:12px;border-style:solid;border-color:#dee0e2;border-top-color:#005ea5;margin-bottom:15px}@media(forced-colors: active){.spinner{forced-color-adjust:none;border-top-color:rgba(0,0,0,0) !important}}@media not (prefers-reduced-motion){.spinner{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}}@media(prefers-reduced-motion){.spinner{transform:rotate(0.125turn)}}.spinner__finished{border-color:#005ea5;-webkit-animation:none;animation:none}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.centre{margin-left:auto;margin-right:auto;text-align:center;display:block}@media(max-width: 256px){.govuk-footer__crown{max-width:100%;max-height:auto}}.govuk-footer{padding-top:25px;padding-bottom:15px;border-top:1px solid #b1b4b6;color:#0b0c0c;background:#f3f2f1}.govuk-template--rebranded .govuk-footer{border-top:10px solid #1d70b8;background:#f4f8fb}.govuk-footer__copyright-logo::before{background:#6e777a}.govuk-template--rebranded .govuk-footer__copyright-logo::before{background:currentcolor}.govuk-button--progress{border-bottom:8px;position:relative}.govuk-button--progress-loading{background-color:#505a5f !important;color:#fff !important;pointer-events:none !important;padding-left:40px !important}@keyframes rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}.govuk-button--progress-loading::before{content:"";border:3px solid hsla(0,0%,100%,.35);border-top:3px solid #fff;border-radius:50%;width:20px;height:20px;animation:rotate 1s infinite linear;position:absolute;top:12% !important;left:8px}@media(prefers-reduced-motion: reduce){.govuk-button--progress-loading{animation:none}}
1
+ @media(max-width: 640px){.govuk-header__navigation-item{border-left:none !important}.govuk-template--rebranded .govuk-header__navigation-list{padding-bottom:0px !important}.govuk-header__navigation-item{padding-top:8px !important}}.frontendUi_header_signOut-item{padding:5px 0px 5px 30px;border-left:1px solid #b1b4b6;margin-left:auto}.frontendUi_header_signOut-item--rebrand{border-left:none;padding:5px 0px 5px 0px;margin-left:auto;font-weight:700 !important}.frontendUi_header__signOut{display:flex;flex-wrap:wrap}.frontendUi-header__content{margin-left:auto}.govuk-header__navigation--signOut{padding:15px 0 15px !important}.govuk-template--rebranded .govuk-header__navigation{padding:15px 0 15px !important}@media(max-width: 640px){.govuk-header__navigation--signOut{padding:18px 0 8px !important}.govuk-template--rebranded .govuk-header__navigation{padding:18px 0 8px !important}}.govuk-template--rebranded .govuk-header__navigation-item a{font-weight:700 !important}.govuk-template--rebranded .govuk-header__navigation-item{padding-top:5px !important}@media(min-width: 20em)and (max-width: 48.0525em){.govuk-template--rebranded .govuk-header__navigation-list{padding-bottom:0px}}@media(max-width: 323px){.govuk-header__logo{padding-right:5px}.frontendUi_header_signOut-item{padding-left:0px}}@media(max-width: 261px){.frontendUi-header__content{margin-left:unset}.govuk-template--rebranded .govuk-header__navigation{padding:0px 0 8px !important}.govuk-header__logotype{max-width:100%;max-height:auto}.govuk-template--rebranded .govuk-header__logo{padding-top:5% !important;padding-bottom:5% !important}}.govuk-tag{font-size:16px;font-weight:bold;line-height:1;display:inline-block;padding-top:5px;padding-right:8px;padding-bottom:4px;padding-left:8px;outline:2px solid rgba(0,0,0,0);outline-offset:-2px;color:#fff !important;background-color:#1d70b8 !important;letter-spacing:1px !important;text-decoration:none !important;text-transform:uppercase !important}@media(max-width: 256px){.govuk-phase-banner__content{display:block}}.language-select{margin:15px 0 15px 0}.language-select__list{margin-top:1em;text-align:right}.language-select__list-item{display:inline-block}.language-select__list-item:first-child::after{content:"";display:inline-block;position:relative;top:.1875em;height:1em;border-right:.09375em solid #000}.language-select__list-item a,.language-select__list-item [aria-current]{padding:.3125em}@media screen and (max-width: 641px){.language-select__list{float:none;text-align:left;padding-bottom:10px;border-bottom:1px solid #b1b4b6}}.spinner{width:80px;height:80px;border-radius:50%;border-width:12px;border-style:solid;border-color:#dee0e2;border-top-color:#005ea5;margin-bottom:15px}@media(forced-colors: active){.spinner{forced-color-adjust:none;border-top-color:rgba(0,0,0,0) !important}}@media not (prefers-reduced-motion){.spinner{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}}@media(prefers-reduced-motion){.spinner{transform:rotate(0.125turn)}}.spinner__finished{border-color:#005ea5;-webkit-animation:none;animation:none}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.centre{margin-left:auto;margin-right:auto;text-align:center;display:block}@media(max-width: 256px){.govuk-footer__crown{max-width:100%;max-height:auto}}.govuk-footer{padding-top:25px;padding-bottom:15px;border-top:1px solid #b1b4b6;color:#0b0c0c;background:#f3f2f1}.govuk-template--rebranded .govuk-footer{border-top:10px solid #1d70b8;background:#f4f8fb}.govuk-footer__copyright-logo::before{background:#6e777a}.govuk-template--rebranded .govuk-footer__copyright-logo::before{background:currentcolor}.govuk-button--progress{position:relative}.govuk-button--progress-loading{background-color:#505a5f !important;color:#fff !important;pointer-events:none !important;padding-left:40px !important}@keyframes rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}.govuk-button--progress-loading::before{content:"";border:3px solid hsla(0,0%,100%,.35);border-top:3px solid #fff;border-radius:50%;width:20px;height:20px;animation:rotate 1s infinite linear;position:absolute;top:12% !important;left:8px}.govuk-progress-button--disabled{opacity:1 !important}@media(prefers-reduced-motion: reduce){.govuk-button--progress-loading{padding-left:10px !important}.govuk-button--progress-loading::before{display:none}}
@@ -1,4 +1,4 @@
1
- import { Request, Response, NextFunction } from "express";
1
+ import { NextFunction, Request, Response } from "express";
2
2
  import { CustomLogger } from "../utils/logger";
3
3
  declare const getGTM: (req: Request, res: Response, next: NextFunction) => void;
4
4
  declare const getAssetPath: (req: Request, res: Response, next: NextFunction) => void;
@@ -7,5 +7,5 @@ declare const getLanguageToggle: (req: Request & {
7
7
  language: string;
8
8
  };
9
9
  }, res: Response, next: NextFunction, customLogger?: CustomLogger) => void;
10
- export { getGTM, getAssetPath, getLanguageToggle };
10
+ export { getAssetPath, getGTM, getLanguageToggle };
11
11
  //# sourceMappingURL=locals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"locals.d.ts","sourceRoot":"","sources":["../../../../src/lib/locals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAa,YAAY,EAAmB,MAAM,iBAAiB,CAAC;AAE3E,QAAA,MAAM,MAAM,GAAI,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IA0BjE,CAAC;AAEF,QAAA,MAAM,YAAY,GAChB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,IAGF,CAAC;AAEF,QAAA,MAAM,iBAAiB,GACrB,KAAK,OAAO,GAAG;IAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAC7C,KAAK,QAAQ,EACb,MAAM,YAAY,EAClB,eAAe,YAAY,KAC1B,IAkBF,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"locals.d.ts","sourceRoot":"","sources":["../../../../src/lib/locals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,YAAY,EAA8B,MAAM,iBAAiB,CAAC;AAE3E,QAAA,MAAM,MAAM,GAAI,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IA0BjE,CAAC;AAEF,QAAA,MAAM,YAAY,GAChB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,IAGF,CAAC;AAEF,QAAA,MAAM,iBAAiB,GACrB,KAAK,OAAO,GAAG;IAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAC7C,KAAK,QAAQ,EACb,MAAM,YAAY,EAClB,eAAe,YAAY,KAC1B,IAqBF,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1,9 +1,9 @@
1
- import { pino } from "pino";
1
+ import type { Logger } from "pino";
2
2
  export type CustomLogger = {
3
3
  trace: (message: string) => void;
4
4
  warn: (message: string) => void;
5
5
  };
6
6
  export declare const setCustomLogger: (customLogger: CustomLogger) => void;
7
- export declare const getLogger: () => pino.Logger | CustomLogger;
7
+ export declare const getLogger: () => Logger | CustomLogger;
8
8
  export declare const resetLogger: () => void;
9
9
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,cAAc,YAAY,SAEzD,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,IAAI,CAAC,MAAM,GAAG,YAW1C,CAAC;AAEF,eAAO,MAAM,WAAW,YAEvB,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAKnC,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,cAAc,YAAY,SAEzD,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,MAAM,GAAG,YAWrC,CAAC;AAEF,eAAO,MAAM,WAAW,YAEvB,CAAC"}
@@ -290,6 +290,12 @@ class Spinner {
290
290
  }
291
291
 
292
292
  function initialiseProgressButtons(document = window.document) {
293
+ // Create a single live region for button status announcements
294
+ const statusRegion = document.createElement('div');
295
+ statusRegion.setAttribute('aria-live', 'assertive');
296
+ statusRegion.setAttribute('role', 'status');
297
+ statusRegion.className = 'govuk-visually-hidden';
298
+ document.body.appendChild(statusRegion);
293
299
  const progressButtons = Array.prototype.slice.call(document.querySelectorAll('[data-frontendui="di-progress-button"]'));
294
300
  function findClosestForm(element) {
295
301
  let el = element;
@@ -301,6 +307,15 @@ function initialiseProgressButtons(document = window.document) {
301
307
  progressButtons.forEach(function (button) {
302
308
  const form = findClosestForm(button);
303
309
  let isSubmitting = false;
310
+ // Handle spacebar press for anchor tags
311
+ if (button.tagName.toLowerCase() === 'a') {
312
+ button.addEventListener('keydown', function (event) {
313
+ if (event.code === 'Space') {
314
+ event.preventDefault();
315
+ button.click();
316
+ }
317
+ });
318
+ }
304
319
  button.addEventListener('click', function (event) {
305
320
  if (isSubmitting) {
306
321
  event.preventDefault();
@@ -343,10 +358,19 @@ function initialiseProgressButtons(document = window.document) {
343
358
  }
344
359
  function handleProgressButtonClick(element, waitingText, longWaitingText, errorPage, isInput) {
345
360
  var originalText = isInput && element instanceof HTMLInputElement ? element.value : element.innerText;
361
+ const statusRegion = document.querySelector('.govuk-visually-hidden[role="status"]');
346
362
  if (typeof element.blur === 'function') {
347
363
  element.blur();
348
364
  }
349
365
  element.setAttribute('data-prevent-double-click', 'true');
366
+ if (element instanceof HTMLButtonElement || element instanceof HTMLInputElement) {
367
+ element.disabled = true;
368
+ }
369
+ else if (element.tagName.toLowerCase() === 'a') {
370
+ element.setAttribute('aria-disabled', 'true');
371
+ element.style.pointerEvents = 'none';
372
+ }
373
+ element.classList.add('govuk-progress-button--disabled');
350
374
  var classes = element.className.split(' ');
351
375
  if (classes.indexOf('govuk-button--progress-loading') === -1) {
352
376
  classes.push('govuk-button--progress-loading');
@@ -358,7 +382,10 @@ function handleProgressButtonClick(element, waitingText, longWaitingText, errorP
358
382
  else {
359
383
  element.innerText = waitingText;
360
384
  }
361
- element.setAttribute('aria-label', waitingText);
385
+ // Announce the initial waiting state
386
+ if (statusRegion) {
387
+ statusRegion.textContent = waitingText;
388
+ }
362
389
  var longWaitTimeout = window.setTimeout(function () {
363
390
  if (isInput && element instanceof HTMLInputElement) {
364
391
  element.value = longWaitingText;
@@ -366,7 +393,10 @@ function handleProgressButtonClick(element, waitingText, longWaitingText, errorP
366
393
  else {
367
394
  element.innerText = longWaitingText;
368
395
  }
369
- element.setAttribute('aria-label', longWaitingText);
396
+ // Announce the long wait state
397
+ if (statusRegion) {
398
+ statusRegion.textContent = longWaitingText;
399
+ }
370
400
  }, 5000);
371
401
  var errorTimeout = window.setTimeout(function () {
372
402
  window.location.href = errorPage;
@@ -378,6 +408,14 @@ function handleProgressButtonClick(element, waitingText, longWaitingText, errorP
378
408
  classes.splice(loadingIndex, 1);
379
409
  element.className = classes.join(' ');
380
410
  }
411
+ if (element instanceof HTMLButtonElement || element instanceof HTMLInputElement) {
412
+ element.disabled = false;
413
+ }
414
+ else if (element.tagName.toLowerCase() === 'a') {
415
+ element.removeAttribute('aria-disabled');
416
+ element.style.pointerEvents = '';
417
+ }
418
+ element.classList.remove('govuk-progress-button--disabled');
381
419
  element.setAttribute('data-prevent-double-click', 'false');
382
420
  if (isInput && element instanceof HTMLInputElement) {
383
421
  element.value = originalText;
@@ -385,7 +423,11 @@ function handleProgressButtonClick(element, waitingText, longWaitingText, errorP
385
423
  else {
386
424
  element.innerText = originalText;
387
425
  }
388
- element.setAttribute('aria-label', originalText);
426
+ // Clear status region without announcement
427
+ const statusRegion = document.querySelector('.govuk-visually-hidden[role="status"]');
428
+ if (statusRegion) {
429
+ statusRegion.textContent = '';
430
+ }
389
431
  window.clearTimeout(errorTimeout);
390
432
  window.clearTimeout(longWaitTimeout);
391
433
  }
@@ -1 +1 @@
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"}
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,QAiF7E"}
@@ -1,5 +1,4 @@
1
1
  .govuk-button--progress{
2
- border-bottom: 8px;
3
2
  position: relative;
4
3
  }
5
4
 
@@ -33,10 +32,18 @@
33
32
  top: 12% !important;
34
33
  left: 8px;
35
34
  }
35
+
36
+ .govuk-progress-button--disabled{
37
+ opacity: 1 !important;
38
+ }
36
39
 
37
40
  @media (prefers-reduced-motion: reduce) {
38
- .govuk-button--progress-loading {
39
- animation: none;
41
+ .govuk-button--progress-loading {
42
+ padding-left: 10px !important;
43
+
44
+ &::before {
45
+ display: none;
46
+ }
40
47
  }
41
48
  }
42
49
 
@@ -65,8 +65,7 @@ treat it as an interactive element - without this it will be
65
65
  </div>
66
66
  </noscript>
67
67
 
68
- <a href="{{ params.href if params.href else '#' }}" role="button" draggable="false" {{- commonAttributes | safe }} class = "{{ classNames }}"
69
- aria-live="assertive" data-frontendui="di-progress-button" data-waiting-text="{{ progressButton.waitingText }}" data-long-waiting-text="{{ progressButton.longWaitingText }}" data-error-page="{{ params.errorPage | default('#') }}" >
68
+ <a href="{{ params.href if params.href else '#' }}" role="button" draggable="false" {{- commonAttributes | safe }} class = "{{ classNames }}" data-frontendui="di-progress-button" data-waiting-text="{{ progressButton.waitingText }}" data-long-waiting-text="{{ progressButton.longWaitingText }}" data-error-page="{{ params.errorPage | default('#') }}" >
70
69
  {% if params.html %}
71
70
  {{ params.html | safe }}
72
71
  {% elseif params.text %}
@@ -86,8 +85,7 @@ aria-live="assertive" data-frontendui="di-progress-button" data-waiting-text="{{
86
85
  </div>
87
86
  </noscript>
88
87
 
89
- <button {%- if params.value %} value="{{ params.value }}"{% endif %}{%- if params.type %} type="{{ params.type }}"{% endif %} {{- buttonAttributes | safe }} {{- commonAttributes | safe }} class = "{{ classNames }}"
90
- aria-live="assertive" data-frontendui="di-progress-button" data-waiting-text="{{ progressButton.waitingText }}" data-long-waiting-text="{{ progressButton.longWaitingText }}" data-error-page="{{ params.errorPage | default('#') }}" >
88
+ <button {%- if params.value %} value="{{ params.value }}"{% endif %}{%- if params.type %} type="{{ params.type }}"{% endif %} {{- buttonAttributes | safe }} {{- commonAttributes | safe }} class = "{{ classNames }}" data-frontendui="di-progress-button" data-waiting-text="{{ progressButton.waitingText }}" data-long-waiting-text="{{ progressButton.longWaitingText }}" data-error-page="{{ params.errorPage | default('#') }}" >
91
89
  {% if params.html %}
92
90
  {{ params.html | safe }}
93
91
  {% elseif params.text %}
@@ -107,8 +105,7 @@ aria-live="assertive" data-frontendui="di-progress-button" data-waiting-text="{{
107
105
  {{ progressButton.noJavascriptMessage }}
108
106
  </div>
109
107
  </noscript>
110
- <input value="{{ params.value }}" type="{{ params.type if params.type else 'submit'}}"{{- buttonAttributes | safe }} {{- commonAttributes | safe }} class = "{{ classNames }}"
111
- aria-live="assertive" data-frontendui="di-progress-button" data-waiting-text="{{ progressButton.waitingText }}" data-long-waiting-text="{{ progressButton.longWaitingText }}" data-error-page="{{ params.errorPage | default('#') }}" >
108
+ <input value="{{ params.value }}" type="{{ params.type if params.type else 'submit'}}"{{- buttonAttributes | safe }} {{- commonAttributes | safe }} class = "{{ classNames }}" data-frontendui="di-progress-button" data-waiting-text="{{ progressButton.waitingText }}" data-long-waiting-text="{{ progressButton.longWaitingText }}" data-error-page="{{ params.errorPage | default('#') }}" >
112
109
  {{- iconHtml | safe | trim | indent(2, true) if iconHtml -}}
113
110
  </div>
114
111
 
@@ -1,4 +1,4 @@
1
- import { Request, Response, NextFunction } from "express";
1
+ import { NextFunction, Request, Response } from "express";
2
2
  import { CustomLogger } from "../utils/logger";
3
3
  declare const getGTM: (req: Request, res: Response, next: NextFunction) => void;
4
4
  declare const getAssetPath: (req: Request, res: Response, next: NextFunction) => void;
@@ -7,5 +7,5 @@ declare const getLanguageToggle: (req: Request & {
7
7
  language: string;
8
8
  };
9
9
  }, res: Response, next: NextFunction, customLogger?: CustomLogger) => void;
10
- export { getGTM, getAssetPath, getLanguageToggle };
10
+ export { getAssetPath, getGTM, getLanguageToggle };
11
11
  //# sourceMappingURL=locals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"locals.d.ts","sourceRoot":"","sources":["../../../../src/lib/locals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAa,YAAY,EAAmB,MAAM,iBAAiB,CAAC;AAE3E,QAAA,MAAM,MAAM,GAAI,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IA0BjE,CAAC;AAEF,QAAA,MAAM,YAAY,GAChB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,IAGF,CAAC;AAEF,QAAA,MAAM,iBAAiB,GACrB,KAAK,OAAO,GAAG;IAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAC7C,KAAK,QAAQ,EACb,MAAM,YAAY,EAClB,eAAe,YAAY,KAC1B,IAkBF,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"locals.d.ts","sourceRoot":"","sources":["../../../../src/lib/locals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,YAAY,EAA8B,MAAM,iBAAiB,CAAC;AAE3E,QAAA,MAAM,MAAM,GAAI,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IA0BjE,CAAC;AAEF,QAAA,MAAM,YAAY,GAChB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,IAGF,CAAC;AAEF,QAAA,MAAM,iBAAiB,GACrB,KAAK,OAAO,GAAG;IAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAC7C,KAAK,QAAQ,EACb,MAAM,YAAY,EAClB,eAAe,YAAY,KAC1B,IAqBF,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1,9 +1,9 @@
1
- import { pino } from "pino";
1
+ import type { Logger } from "pino";
2
2
  export type CustomLogger = {
3
3
  trace: (message: string) => void;
4
4
  warn: (message: string) => void;
5
5
  };
6
6
  export declare const setCustomLogger: (customLogger: CustomLogger) => void;
7
- export declare const getLogger: () => pino.Logger | CustomLogger;
7
+ export declare const getLogger: () => Logger | CustomLogger;
8
8
  export declare const resetLogger: () => void;
9
9
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,cAAc,YAAY,SAEzD,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,IAAI,CAAC,MAAM,GAAG,YAW1C,CAAC;AAEF,eAAO,MAAM,WAAW,YAEvB,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAKnC,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,cAAc,YAAY,SAEzD,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,MAAM,GAAG,YAWrC,CAAC;AAEF,eAAO,MAAM,WAAW,YAEvB,CAAC"}
@@ -288,6 +288,12 @@ class Spinner {
288
288
  }
289
289
 
290
290
  function initialiseProgressButtons(document = window.document) {
291
+ // Create a single live region for button status announcements
292
+ const statusRegion = document.createElement('div');
293
+ statusRegion.setAttribute('aria-live', 'assertive');
294
+ statusRegion.setAttribute('role', 'status');
295
+ statusRegion.className = 'govuk-visually-hidden';
296
+ document.body.appendChild(statusRegion);
291
297
  const progressButtons = Array.prototype.slice.call(document.querySelectorAll('[data-frontendui="di-progress-button"]'));
292
298
  function findClosestForm(element) {
293
299
  let el = element;
@@ -299,6 +305,15 @@ function initialiseProgressButtons(document = window.document) {
299
305
  progressButtons.forEach(function (button) {
300
306
  const form = findClosestForm(button);
301
307
  let isSubmitting = false;
308
+ // Handle spacebar press for anchor tags
309
+ if (button.tagName.toLowerCase() === 'a') {
310
+ button.addEventListener('keydown', function (event) {
311
+ if (event.code === 'Space') {
312
+ event.preventDefault();
313
+ button.click();
314
+ }
315
+ });
316
+ }
302
317
  button.addEventListener('click', function (event) {
303
318
  if (isSubmitting) {
304
319
  event.preventDefault();
@@ -341,10 +356,19 @@ function initialiseProgressButtons(document = window.document) {
341
356
  }
342
357
  function handleProgressButtonClick(element, waitingText, longWaitingText, errorPage, isInput) {
343
358
  var originalText = isInput && element instanceof HTMLInputElement ? element.value : element.innerText;
359
+ const statusRegion = document.querySelector('.govuk-visually-hidden[role="status"]');
344
360
  if (typeof element.blur === 'function') {
345
361
  element.blur();
346
362
  }
347
363
  element.setAttribute('data-prevent-double-click', 'true');
364
+ if (element instanceof HTMLButtonElement || element instanceof HTMLInputElement) {
365
+ element.disabled = true;
366
+ }
367
+ else if (element.tagName.toLowerCase() === 'a') {
368
+ element.setAttribute('aria-disabled', 'true');
369
+ element.style.pointerEvents = 'none';
370
+ }
371
+ element.classList.add('govuk-progress-button--disabled');
348
372
  var classes = element.className.split(' ');
349
373
  if (classes.indexOf('govuk-button--progress-loading') === -1) {
350
374
  classes.push('govuk-button--progress-loading');
@@ -356,7 +380,10 @@ function handleProgressButtonClick(element, waitingText, longWaitingText, errorP
356
380
  else {
357
381
  element.innerText = waitingText;
358
382
  }
359
- element.setAttribute('aria-label', waitingText);
383
+ // Announce the initial waiting state
384
+ if (statusRegion) {
385
+ statusRegion.textContent = waitingText;
386
+ }
360
387
  var longWaitTimeout = window.setTimeout(function () {
361
388
  if (isInput && element instanceof HTMLInputElement) {
362
389
  element.value = longWaitingText;
@@ -364,7 +391,10 @@ function handleProgressButtonClick(element, waitingText, longWaitingText, errorP
364
391
  else {
365
392
  element.innerText = longWaitingText;
366
393
  }
367
- element.setAttribute('aria-label', longWaitingText);
394
+ // Announce the long wait state
395
+ if (statusRegion) {
396
+ statusRegion.textContent = longWaitingText;
397
+ }
368
398
  }, 5000);
369
399
  var errorTimeout = window.setTimeout(function () {
370
400
  window.location.href = errorPage;
@@ -376,6 +406,14 @@ function handleProgressButtonClick(element, waitingText, longWaitingText, errorP
376
406
  classes.splice(loadingIndex, 1);
377
407
  element.className = classes.join(' ');
378
408
  }
409
+ if (element instanceof HTMLButtonElement || element instanceof HTMLInputElement) {
410
+ element.disabled = false;
411
+ }
412
+ else if (element.tagName.toLowerCase() === 'a') {
413
+ element.removeAttribute('aria-disabled');
414
+ element.style.pointerEvents = '';
415
+ }
416
+ element.classList.remove('govuk-progress-button--disabled');
379
417
  element.setAttribute('data-prevent-double-click', 'false');
380
418
  if (isInput && element instanceof HTMLInputElement) {
381
419
  element.value = originalText;
@@ -383,7 +421,11 @@ function handleProgressButtonClick(element, waitingText, longWaitingText, errorP
383
421
  else {
384
422
  element.innerText = originalText;
385
423
  }
386
- element.setAttribute('aria-label', originalText);
424
+ // Clear status region without announcement
425
+ const statusRegion = document.querySelector('.govuk-visually-hidden[role="status"]');
426
+ if (statusRegion) {
427
+ statusRegion.textContent = '';
428
+ }
387
429
  window.clearTimeout(errorTimeout);
388
430
  window.clearTimeout(longWaitTimeout);
389
431
  }
@@ -1 +1 @@
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"}
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,QAiF7E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@govuk-one-login/frontend-ui",
3
- "version": "4.0.1",
3
+ "version": "4.1.1",
4
4
  "description": "",
5
5
  "main": "build/cjs/backend/index.cjs",
6
6
  "module": "build/esm/backend/index.js",
@@ -39,12 +39,12 @@
39
39
  "homepage": "https://github.com/govuk-one-login/govuk-one-login-frontend#readme",
40
40
  "dependencies": {
41
41
  "js-yaml": "^4.1.0",
42
- "pino": "8.20.0"
42
+ "pino": "^10.1.0"
43
43
  },
44
44
  "peerDependencies": {
45
+ "@govuk-one-login/frontend-analytics": " ^3.0.1 || ^4.0.3",
45
46
  "express": "^5.1.0 || >= 4.21.2",
46
- "govuk-frontend": "^4.10.1 || ^5.0.0",
47
- "@govuk-one-login/frontend-analytics": " ^3.0.1 || ^4.0.3"
47
+ "govuk-frontend": "^4.10.1 || ^5.0.0"
48
48
  },
49
49
  "exports": {
50
50
  ".": {
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "types": "./build/esm/backend/index.d.ts",
60
60
  "optionalDependencies": {
61
- "hmpo-components": "^7.1.0",
62
- "@govuk-one-login/frontend-analytics": "^4.0.5"
61
+ "@govuk-one-login/frontend-analytics": "^4.0.5",
62
+ "hmpo-components": "^7.1.0"
63
63
  }
64
64
  }