govuk_tech_docs 3.0.1 → 3.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.
Potentially problematic release.
This version of govuk_tech_docs might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/govuk_tech_docs/version.rb +1 -1
- data/lib/source/layouts/_header.erb +3 -3
- data/lib/source/layouts/core.erb +1 -1
- data/node_modules/govuk-frontend/govuk/all.js +272 -75
- data/node_modules/govuk-frontend/govuk/components/accordion/_index.scss +275 -98
- data/node_modules/govuk-frontend/govuk/components/accordion/accordion.js +169 -65
- data/node_modules/govuk-frontend/govuk/components/button/_index.scss +3 -4
- data/node_modules/govuk-frontend/govuk/components/button/button.js +2 -2
- data/node_modules/govuk-frontend/govuk/components/character-count/character-count.js +3 -3
- data/node_modules/govuk-frontend/govuk/components/checkboxes/_index.scss +14 -0
- data/node_modules/govuk-frontend/govuk/components/checkboxes/checkboxes.js +8 -10
- data/node_modules/govuk-frontend/govuk/components/cookie-banner/_index.scss +0 -2
- data/node_modules/govuk-frontend/govuk/components/details/_index.scss +2 -1
- data/node_modules/govuk-frontend/govuk/components/details/details.js +2 -2
- data/node_modules/govuk-frontend/govuk/components/error-message/_index.scss +1 -0
- data/node_modules/govuk-frontend/govuk/components/error-summary/error-summary.js +2 -2
- data/node_modules/govuk-frontend/govuk/components/file-upload/_index.scss +1 -0
- data/node_modules/govuk-frontend/govuk/components/footer/_index.scss +6 -37
- data/node_modules/govuk-frontend/govuk/components/header/_index.scss +10 -4
- data/node_modules/govuk-frontend/govuk/components/header/header.js +4 -4
- data/node_modules/govuk-frontend/govuk/components/hint/_index.scss +1 -3
- data/node_modules/govuk-frontend/govuk/components/input/_index.scss +1 -1
- data/node_modules/govuk-frontend/govuk/components/notification-banner/notification-banner.js +499 -2
- data/node_modules/govuk-frontend/govuk/components/panel/_index.scss +13 -1
- data/node_modules/govuk-frontend/govuk/components/radios/_index.scss +14 -0
- data/node_modules/govuk-frontend/govuk/components/radios/radios.js +4 -4
- data/node_modules/govuk-frontend/govuk/components/select/_index.scss +1 -1
- data/node_modules/govuk-frontend/govuk/components/skip-link/_index.scss +13 -0
- data/node_modules/govuk-frontend/govuk/components/skip-link/skip-link.js +1108 -0
- data/node_modules/govuk-frontend/govuk/components/summary-list/_index.scss +15 -23
- data/node_modules/govuk-frontend/govuk/components/tabs/_index.scss +2 -2
- data/node_modules/govuk-frontend/govuk/components/tabs/tabs.js +2 -2
- data/node_modules/govuk-frontend/govuk/components/tag/_index.scss +0 -5
- data/node_modules/govuk-frontend/govuk/components/textarea/_index.scss +1 -1
- data/node_modules/govuk-frontend/govuk/core/_all.scss +0 -1
- data/node_modules/govuk-frontend/govuk/core/_global-styles.scss +0 -6
- data/node_modules/govuk-frontend/govuk/core/_links.scss +0 -6
- data/node_modules/govuk-frontend/govuk/core/_lists.scss +0 -6
- data/node_modules/govuk-frontend/govuk/core/_section-break.scss +0 -6
- data/node_modules/govuk-frontend/govuk/core/_typography.scss +0 -6
- data/node_modules/govuk-frontend/govuk/helpers/_colour.scss +2 -2
- data/node_modules/govuk-frontend/govuk/helpers/_spacing.scss +22 -4
- data/node_modules/govuk-frontend/govuk/objects/_all.scss +1 -0
- data/node_modules/govuk-frontend/govuk/objects/_main-wrapper.scss +15 -30
- data/node_modules/govuk-frontend/govuk/{core → objects}/_template.scss +1 -5
- data/node_modules/govuk-frontend/govuk/overrides/_all.scss +1 -0
- data/node_modules/govuk-frontend/govuk/overrides/_display.scss +0 -6
- data/node_modules/govuk-frontend/govuk/overrides/_spacing.scss +0 -6
- data/node_modules/govuk-frontend/govuk/overrides/_text-align.scss +14 -0
- data/node_modules/govuk-frontend/govuk/overrides/_typography.scss +0 -6
- data/node_modules/govuk-frontend/govuk/overrides/_width.scss +0 -6
- data/node_modules/govuk-frontend/govuk/settings/_colours-organisations.scss +3 -0
- data/node_modules/govuk-frontend/govuk/settings/_measurements.scss +0 -10
- data/node_modules/govuk-frontend/govuk/tools/_all.scss +0 -1
- data/package-lock.json +3 -3
- data/package.json +1 -1
- metadata +5 -4
- data/node_modules/govuk-frontend/govuk/tools/_iff.scss +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b05aaaeb08b75633793f5ede8102ef35d54cedbe6bc419b9fe262a3596d6cfef
|
4
|
+
data.tar.gz: 30ab85794e056634591d692999364da7644908653e06d2707aa15eeff9b5bfea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 406187054e9b14fd631fb56a2602f8c607ab2abfe8be466673ffee99fba6451ebe684dca40e53270b66b5b1a6b12142336ad26124335b33b02205e13005290e8
|
7
|
+
data.tar.gz: fc0afcd3567241e487bb75fbfebb26561ee8b6c9dd0a50d5f2d8252ea2d8a95c71976ae2540ff1f58e2d89886234c25b6d6b726fb74e618a1fba05ae97b0303d
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 3.1.0
|
6
|
+
|
7
|
+
### New features
|
8
|
+
|
9
|
+
There are some steps you should follow as the Technical Documentation Template (TDT) now uses GOV.UK Frontend 4.0.0.
|
10
|
+
|
11
|
+
1. Update your documentation site to use the latest template version. You can [follow the TDT guidance on using the latest template version](https://tdt-documentation.london.cloudapps.digital/maintain_project/use_latest_template/).
|
12
|
+
2. Check your documentation site displays correctly. If your site does not display correctly, you can refer to the [GOV.UK Frontend 4.0.0 release note](https://github.com/alphagov/govuk-frontend/releases/tag/v4.0.0) for more information.
|
13
|
+
|
5
14
|
## 3.0.1
|
6
15
|
|
7
16
|
### Fixes
|
@@ -41,9 +41,9 @@
|
|
41
41
|
</div>
|
42
42
|
<% if config[:tech_docs][:header_links] %>
|
43
43
|
<div class="govuk-header__content">
|
44
|
-
<
|
45
|
-
|
46
|
-
<ul id="navigation" class="govuk-header__navigation
|
44
|
+
<nav class="govuk-header__navigation govuk-header__navigation--end" aria-label="Menu">
|
45
|
+
<button type="button" class="govuk-header__menu-button govuk-js-header-toggle" aria-controls="navigation" aria-label="Show or hide menu">Menu</button>
|
46
|
+
<ul id="navigation" class="govuk-header__navigation-list">
|
47
47
|
<% config[:tech_docs][:header_links].each do |title, path| %>
|
48
48
|
<li class="govuk-header__navigation-item<% if active_page(path) %> govuk-header__navigation-item--active<% end %>">
|
49
49
|
<a class="govuk-header__link" href="<%= url_for path %>"><%= title %></a>
|
data/lib/source/layouts/core.erb
CHANGED
@@ -27,7 +27,7 @@
|
|
27
27
|
|
28
28
|
<div class="app-pane">
|
29
29
|
<div class="app-pane__header toc-open-disabled">
|
30
|
-
<a href="#content" class="govuk-skip-link">Skip to main content</a>
|
30
|
+
<a href="#content" class="govuk-skip-link" data-module="govuk-skip-link">Skip to main content</a>
|
31
31
|
|
32
32
|
<%= partial 'layouts/header' %>
|
33
33
|
</div>
|
@@ -777,19 +777,28 @@ function Accordion ($module) {
|
|
777
777
|
this.$module = $module;
|
778
778
|
this.moduleId = $module.getAttribute('id');
|
779
779
|
this.$sections = $module.querySelectorAll('.govuk-accordion__section');
|
780
|
-
this.$
|
780
|
+
this.$showAllButton = '';
|
781
781
|
this.browserSupportsSessionStorage = helper.checkForSessionStorage();
|
782
782
|
|
783
783
|
this.controlsClass = 'govuk-accordion__controls';
|
784
|
-
this.
|
785
|
-
this.
|
784
|
+
this.showAllClass = 'govuk-accordion__show-all';
|
785
|
+
this.showAllTextClass = 'govuk-accordion__show-all-text';
|
786
786
|
|
787
|
+
this.sectionExpandedClass = 'govuk-accordion__section--expanded';
|
788
|
+
this.sectionButtonClass = 'govuk-accordion__section-button';
|
787
789
|
this.sectionHeaderClass = 'govuk-accordion__section-header';
|
788
|
-
this.sectionHeaderFocusedClass = 'govuk-accordion__section-header--focused';
|
789
790
|
this.sectionHeadingClass = 'govuk-accordion__section-heading';
|
791
|
+
this.sectionHeadingTextClass = 'govuk-accordion__section-heading-text';
|
792
|
+
this.sectionHeadingTextFocusClass = 'govuk-accordion__section-heading-text-focus';
|
793
|
+
|
794
|
+
this.sectionShowHideToggleClass = 'govuk-accordion__section-toggle';
|
795
|
+
this.sectionShowHideToggleFocusClass = 'govuk-accordion__section-toggle-focus';
|
796
|
+
this.sectionShowHideTextClass = 'govuk-accordion__section-toggle-text';
|
797
|
+
this.upChevronIconClass = 'govuk-accordion-nav__chevron';
|
798
|
+
this.downChevronIconClass = 'govuk-accordion-nav__chevron--down';
|
799
|
+
|
790
800
|
this.sectionSummaryClass = 'govuk-accordion__section-summary';
|
791
|
-
this.
|
792
|
-
this.sectionExpandedClass = 'govuk-accordion__section--expanded';
|
801
|
+
this.sectionSummaryFocusClass = 'govuk-accordion__section-summary-focus';
|
793
802
|
}
|
794
803
|
|
795
804
|
// Initialize component
|
@@ -800,32 +809,39 @@ Accordion.prototype.init = function () {
|
|
800
809
|
}
|
801
810
|
|
802
811
|
this.initControls();
|
803
|
-
|
804
812
|
this.initSectionHeaders();
|
805
813
|
|
806
|
-
// See if "
|
814
|
+
// See if "Show all sections" button text should be updated
|
807
815
|
var areAllSectionsOpen = this.checkIfAllSectionsOpen();
|
808
|
-
this.
|
816
|
+
this.updateShowAllButton(areAllSectionsOpen);
|
809
817
|
};
|
810
818
|
|
811
819
|
// Initialise controls and set attributes
|
812
820
|
Accordion.prototype.initControls = function () {
|
813
|
-
// Create "
|
814
|
-
this.$
|
815
|
-
this.$
|
816
|
-
this.$
|
817
|
-
this.$
|
818
|
-
|
819
|
-
|
821
|
+
// Create "Show all" button and set attributes
|
822
|
+
this.$showAllButton = document.createElement('button');
|
823
|
+
this.$showAllButton.setAttribute('type', 'button');
|
824
|
+
this.$showAllButton.setAttribute('class', this.showAllClass);
|
825
|
+
this.$showAllButton.setAttribute('aria-expanded', 'false');
|
826
|
+
|
827
|
+
// Create icon, add to element
|
828
|
+
var $icon = document.createElement('span');
|
829
|
+
$icon.classList.add(this.upChevronIconClass);
|
830
|
+
this.$showAllButton.appendChild($icon);
|
820
831
|
|
821
832
|
// Create control wrapper and add controls to it
|
822
|
-
var accordionControls = document.createElement('div');
|
823
|
-
accordionControls.setAttribute('class', this.controlsClass);
|
824
|
-
accordionControls.appendChild(this.$
|
825
|
-
this.$module.insertBefore(accordionControls, this.$module.firstChild);
|
833
|
+
var $accordionControls = document.createElement('div');
|
834
|
+
$accordionControls.setAttribute('class', this.controlsClass);
|
835
|
+
$accordionControls.appendChild(this.$showAllButton);
|
836
|
+
this.$module.insertBefore($accordionControls, this.$module.firstChild);
|
837
|
+
|
838
|
+
// Build additional wrapper for Show all toggle text and place after icon
|
839
|
+
var $wrappershowAllText = document.createElement('span');
|
840
|
+
$wrappershowAllText.classList.add(this.showAllTextClass);
|
841
|
+
this.$showAllButton.appendChild($wrappershowAllText);
|
826
842
|
|
827
|
-
// Handle events
|
828
|
-
this.$
|
843
|
+
// Handle click events on the show/hide all button
|
844
|
+
this.$showAllButton.addEventListener('click', this.onShowOrHideAllToggle.bind(this));
|
829
845
|
};
|
830
846
|
|
831
847
|
// Initialise section headers
|
@@ -833,13 +849,12 @@ Accordion.prototype.initSectionHeaders = function () {
|
|
833
849
|
// Loop through section headers
|
834
850
|
nodeListForEach(this.$sections, function ($section, i) {
|
835
851
|
// Set header attributes
|
836
|
-
var header = $section.querySelector('.' + this.sectionHeaderClass);
|
837
|
-
this.
|
838
|
-
|
852
|
+
var $header = $section.querySelector('.' + this.sectionHeaderClass);
|
853
|
+
this.constructHeaderMarkup($header, i);
|
839
854
|
this.setExpanded(this.isExpanded($section), $section);
|
840
855
|
|
841
856
|
// Handle events
|
842
|
-
header.addEventListener('click', this.onSectionToggle.bind(this, $section));
|
857
|
+
$header.addEventListener('click', this.onSectionToggle.bind(this, $section));
|
843
858
|
|
844
859
|
// See if there is any state stored in sessionStorage and set the sections to
|
845
860
|
// open or closed.
|
@@ -847,51 +862,100 @@ Accordion.prototype.initSectionHeaders = function () {
|
|
847
862
|
}.bind(this));
|
848
863
|
};
|
849
864
|
|
850
|
-
|
851
|
-
Accordion.prototype.initHeaderAttributes = function ($headerWrapper, index) {
|
852
|
-
var $module = this;
|
865
|
+
Accordion.prototype.constructHeaderMarkup = function ($headerWrapper, index) {
|
853
866
|
var $span = $headerWrapper.querySelector('.' + this.sectionButtonClass);
|
854
867
|
var $heading = $headerWrapper.querySelector('.' + this.sectionHeadingClass);
|
855
868
|
var $summary = $headerWrapper.querySelector('.' + this.sectionSummaryClass);
|
856
869
|
|
857
|
-
//
|
870
|
+
// Create a button element that will replace the '.govuk-accordion__section-button' span
|
858
871
|
var $button = document.createElement('button');
|
859
872
|
$button.setAttribute('type', 'button');
|
860
|
-
$button.setAttribute('id', this.moduleId + '-heading-' + (index + 1));
|
861
873
|
$button.setAttribute('aria-controls', this.moduleId + '-content-' + (index + 1));
|
862
874
|
|
863
875
|
// Copy all attributes (https://developer.mozilla.org/en-US/docs/Web/API/Element/attributes) from $span to $button
|
864
876
|
for (var i = 0; i < $span.attributes.length; i++) {
|
865
877
|
var attr = $span.attributes.item(i);
|
866
|
-
|
878
|
+
// Add all attributes but not ID as this is being added to
|
879
|
+
// the section heading ($headingText)
|
880
|
+
if (attr.nodeName !== 'id') {
|
881
|
+
$button.setAttribute(attr.nodeName, attr.nodeValue);
|
882
|
+
}
|
867
883
|
}
|
868
884
|
|
869
|
-
|
870
|
-
|
871
|
-
|
885
|
+
// Create container for heading text so it can be styled
|
886
|
+
var $headingText = document.createElement('span');
|
887
|
+
$headingText.classList.add(this.sectionHeadingTextClass);
|
888
|
+
// Copy the span ID to the heading text to allow it to be referenced by `aria-labelledby` on the
|
889
|
+
// hidden content area without "Show this section"
|
890
|
+
$headingText.id = $span.id;
|
891
|
+
|
892
|
+
// Create an inner heading text container to limit the width of the focus state
|
893
|
+
var $headingTextFocus = document.createElement('span');
|
894
|
+
$headingTextFocus.classList.add(this.sectionHeadingTextFocusClass);
|
895
|
+
$headingText.appendChild($headingTextFocus);
|
896
|
+
// span could contain HTML elements (see https://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#phrasing-content)
|
897
|
+
$headingTextFocus.innerHTML = $span.innerHTML;
|
898
|
+
|
899
|
+
// Create container for show / hide icons and text.
|
900
|
+
var $showToggle = document.createElement('span');
|
901
|
+
$showToggle.classList.add(this.sectionShowHideToggleClass);
|
902
|
+
// Tell Google not to index the 'show' text as part of the heading
|
903
|
+
// For the snippet to work with JavaScript, it must be added before adding the page element to the
|
904
|
+
// page's DOM. See https://developers.google.com/search/docs/advanced/robots/robots_meta_tag#data-nosnippet-attr
|
905
|
+
$showToggle.setAttribute('data-nosnippet', '');
|
906
|
+
// Create an inner container to limit the width of the focus state
|
907
|
+
var $showToggleFocus = document.createElement('span');
|
908
|
+
$showToggleFocus.classList.add(this.sectionShowHideToggleFocusClass);
|
909
|
+
$showToggle.appendChild($showToggleFocus);
|
910
|
+
// Create wrapper for the show / hide text. Append text after the show/hide icon
|
911
|
+
var $showToggleText = document.createElement('span');
|
912
|
+
var $icon = document.createElement('span');
|
913
|
+
$icon.classList.add(this.upChevronIconClass);
|
914
|
+
$showToggleFocus.appendChild($icon);
|
915
|
+
$showToggleText.classList.add(this.sectionShowHideTextClass);
|
916
|
+
$showToggleFocus.appendChild($showToggleText);
|
917
|
+
|
918
|
+
// Append elements to the button:
|
919
|
+
// 1. Heading text
|
920
|
+
// 2. Punctuation
|
921
|
+
// 3. (Optional: Summary line followed by punctuation)
|
922
|
+
// 4. Show / hide toggle
|
923
|
+
$button.appendChild($headingText);
|
924
|
+
$button.appendChild(this.getButtonPunctuationEl());
|
925
|
+
|
926
|
+
// If summary content exists add to DOM in correct order
|
927
|
+
if (typeof ($summary) !== 'undefined' && $summary !== null) {
|
928
|
+
// Create a new `span` element and copy the summary line content from the original `div` to the
|
929
|
+
// new `span`
|
930
|
+
// This is because the summary line text is now inside a button element, which can only contain
|
931
|
+
// phrasing content
|
932
|
+
var $summarySpan = document.createElement('span');
|
933
|
+
// Create an inner summary container to limit the width of the summary focus state
|
934
|
+
var $summarySpanFocus = document.createElement('span');
|
935
|
+
$summarySpanFocus.classList.add(this.sectionSummaryFocusClass);
|
936
|
+
$summarySpan.appendChild($summarySpanFocus);
|
937
|
+
|
938
|
+
// Get original attributes, and pass them to the replacement
|
939
|
+
for (var j = 0, l = $summary.attributes.length; j < l; ++j) {
|
940
|
+
var nodeName = $summary.attributes.item(j).nodeName;
|
941
|
+
var nodeValue = $summary.attributes.item(j).nodeValue;
|
942
|
+
$summarySpan.setAttribute(nodeName, nodeValue);
|
872
943
|
}
|
873
|
-
});
|
874
944
|
|
875
|
-
|
876
|
-
$
|
877
|
-
});
|
945
|
+
// Copy original contents of summary to the new summary span
|
946
|
+
$summarySpanFocus.innerHTML = $summary.innerHTML;
|
878
947
|
|
879
|
-
|
880
|
-
$
|
948
|
+
// Replace the original summary `div` with the new summary `span`
|
949
|
+
$summary.parentNode.replaceChild($summarySpan, $summary);
|
950
|
+
|
951
|
+
$button.appendChild($summarySpan);
|
952
|
+
$button.appendChild(this.getButtonPunctuationEl());
|
881
953
|
}
|
882
954
|
|
883
|
-
|
884
|
-
$button.innerHTML = $span.innerHTML;
|
955
|
+
$button.appendChild($showToggle);
|
885
956
|
|
886
957
|
$heading.removeChild($span);
|
887
958
|
$heading.appendChild($button);
|
888
|
-
|
889
|
-
// Add "+/-" icon
|
890
|
-
var icon = document.createElement('span');
|
891
|
-
icon.className = this.iconClass;
|
892
|
-
icon.setAttribute('aria-hidden', 'true');
|
893
|
-
|
894
|
-
$button.appendChild(icon);
|
895
959
|
};
|
896
960
|
|
897
961
|
// When section toggled, set and store state
|
@@ -904,10 +968,9 @@ Accordion.prototype.onSectionToggle = function ($section) {
|
|
904
968
|
};
|
905
969
|
|
906
970
|
// When Open/Close All toggled, set and store state
|
907
|
-
Accordion.prototype.
|
971
|
+
Accordion.prototype.onShowOrHideAllToggle = function () {
|
908
972
|
var $module = this;
|
909
973
|
var $sections = this.$sections;
|
910
|
-
|
911
974
|
var nowExpanded = !this.checkIfAllSectionsOpen();
|
912
975
|
|
913
976
|
nodeListForEach($sections, function ($section) {
|
@@ -916,23 +979,37 @@ Accordion.prototype.onOpenOrCloseAllToggle = function () {
|
|
916
979
|
$module.storeState($section);
|
917
980
|
});
|
918
981
|
|
919
|
-
$module.
|
982
|
+
$module.updateShowAllButton(nowExpanded);
|
920
983
|
};
|
921
984
|
|
922
985
|
// Set section attributes when opened/closed
|
923
986
|
Accordion.prototype.setExpanded = function (expanded, $section) {
|
987
|
+
var $icon = $section.querySelector('.' + this.upChevronIconClass);
|
988
|
+
var $showHideText = $section.querySelector('.' + this.sectionShowHideTextClass);
|
924
989
|
var $button = $section.querySelector('.' + this.sectionButtonClass);
|
990
|
+
var $newButtonText = expanded ? 'Hide' : 'Show';
|
991
|
+
|
992
|
+
// Build additional copy of "this section" for assistive technology and place inside toggle link
|
993
|
+
var $visuallyHiddenText = document.createElement('span');
|
994
|
+
$visuallyHiddenText.classList.add('govuk-visually-hidden');
|
995
|
+
$visuallyHiddenText.innerHTML = ' this section';
|
996
|
+
|
997
|
+
$showHideText.innerHTML = $newButtonText;
|
998
|
+
$showHideText.appendChild($visuallyHiddenText);
|
925
999
|
$button.setAttribute('aria-expanded', expanded);
|
926
1000
|
|
1001
|
+
// Swap icon, change class
|
927
1002
|
if (expanded) {
|
928
1003
|
$section.classList.add(this.sectionExpandedClass);
|
1004
|
+
$icon.classList.remove(this.downChevronIconClass);
|
929
1005
|
} else {
|
930
1006
|
$section.classList.remove(this.sectionExpandedClass);
|
1007
|
+
$icon.classList.add(this.downChevronIconClass);
|
931
1008
|
}
|
932
1009
|
|
933
|
-
// See if "
|
1010
|
+
// See if "Show all sections" button text should be updated
|
934
1011
|
var areAllSectionsOpen = this.checkIfAllSectionsOpen();
|
935
|
-
this.
|
1012
|
+
this.updateShowAllButton(areAllSectionsOpen);
|
936
1013
|
};
|
937
1014
|
|
938
1015
|
// Get state of section
|
@@ -951,12 +1028,20 @@ Accordion.prototype.checkIfAllSectionsOpen = function () {
|
|
951
1028
|
return areAllSectionsOpen
|
952
1029
|
};
|
953
1030
|
|
954
|
-
// Update "
|
955
|
-
Accordion.prototype.
|
956
|
-
var
|
957
|
-
|
958
|
-
|
959
|
-
this.$
|
1031
|
+
// Update "Show all sections" button
|
1032
|
+
Accordion.prototype.updateShowAllButton = function (expanded) {
|
1033
|
+
var $showAllIcon = this.$showAllButton.querySelector('.' + this.upChevronIconClass);
|
1034
|
+
var $showAllText = this.$showAllButton.querySelector('.' + this.showAllTextClass);
|
1035
|
+
var newButtonText = expanded ? 'Hide all sections' : 'Show all sections';
|
1036
|
+
this.$showAllButton.setAttribute('aria-expanded', expanded);
|
1037
|
+
$showAllText.innerHTML = newButtonText;
|
1038
|
+
|
1039
|
+
// Swap icon, toggle class
|
1040
|
+
if (expanded) {
|
1041
|
+
$showAllIcon.classList.remove(this.downChevronIconClass);
|
1042
|
+
} else {
|
1043
|
+
$showAllIcon.classList.add(this.downChevronIconClass);
|
1044
|
+
}
|
960
1045
|
};
|
961
1046
|
|
962
1047
|
// Check for `window.sessionStorage`, and that it actually works.
|
@@ -980,7 +1065,7 @@ var helper = {
|
|
980
1065
|
// Set the state of the accordions in sessionStorage
|
981
1066
|
Accordion.prototype.storeState = function ($section) {
|
982
1067
|
if (this.browserSupportsSessionStorage) {
|
983
|
-
// We need a unique way of identifying each content in the
|
1068
|
+
// We need a unique way of identifying each content in the Accordion. Since
|
984
1069
|
// an `#id` should be unique and an `id` is required for `aria-` attributes
|
985
1070
|
// `id` can be safely used.
|
986
1071
|
var $button = $section.querySelector('.' + this.sectionButtonClass);
|
@@ -1021,6 +1106,25 @@ Accordion.prototype.setInitialState = function ($section) {
|
|
1021
1106
|
}
|
1022
1107
|
};
|
1023
1108
|
|
1109
|
+
/**
|
1110
|
+
* Create an element to improve semantics of the section button with punctuation
|
1111
|
+
* @return {object} DOM element
|
1112
|
+
*
|
1113
|
+
* Used to add pause (with a comma) for assistive technology.
|
1114
|
+
* Example: [heading]Section A ,[pause] Show this section.
|
1115
|
+
* https://accessibility.blog.gov.uk/2017/12/18/what-working-on-gov-uk-navigation-taught-us-about-accessibility/
|
1116
|
+
*
|
1117
|
+
* Adding punctuation to the button can also improve its general semantics by dividing its contents
|
1118
|
+
* into thematic chunks.
|
1119
|
+
* See https://github.com/alphagov/govuk-frontend/issues/2327#issuecomment-922957442
|
1120
|
+
*/
|
1121
|
+
Accordion.prototype.getButtonPunctuationEl = function () {
|
1122
|
+
var $punctuationEl = document.createElement('span');
|
1123
|
+
$punctuationEl.classList.add('govuk-visually-hidden', 'govuk-accordion__section-heading-divider');
|
1124
|
+
$punctuationEl.innerHTML = ', ';
|
1125
|
+
return $punctuationEl
|
1126
|
+
};
|
1127
|
+
|
1024
1128
|
(function(undefined) {
|
1025
1129
|
|
1026
1130
|
// Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Window/detect.js
|
@@ -1498,7 +1602,7 @@ function CharacterCount ($module) {
|
|
1498
1602
|
this.$module = $module;
|
1499
1603
|
this.$textarea = $module.querySelector('.govuk-js-character-count');
|
1500
1604
|
if (this.$textarea) {
|
1501
|
-
this.$countMessage =
|
1605
|
+
this.$countMessage = document.getElementById(this.$textarea.id + '-info');
|
1502
1606
|
}
|
1503
1607
|
}
|
1504
1608
|
|
@@ -1697,7 +1801,7 @@ Checkboxes.prototype.init = function () {
|
|
1697
1801
|
|
1698
1802
|
// Skip checkboxes without data-aria-controls attributes, or where the
|
1699
1803
|
// target element does not exist.
|
1700
|
-
if (!target ||
|
1804
|
+
if (!target || !document.getElementById(target)) {
|
1701
1805
|
return
|
1702
1806
|
}
|
1703
1807
|
|
@@ -1741,7 +1845,7 @@ Checkboxes.prototype.syncAllConditionalReveals = function () {
|
|
1741
1845
|
* @param {HTMLInputElement} $input Checkbox input
|
1742
1846
|
*/
|
1743
1847
|
Checkboxes.prototype.syncConditionalRevealWithInputState = function ($input) {
|
1744
|
-
var $target =
|
1848
|
+
var $target = document.getElementById($input.getAttribute('aria-controls'));
|
1745
1849
|
|
1746
1850
|
if ($target && $target.classList.contains('govuk-checkboxes__conditional')) {
|
1747
1851
|
var inputIsChecked = $input.checked;
|
@@ -1764,10 +1868,9 @@ Checkboxes.prototype.unCheckAllInputsExcept = function ($input) {
|
|
1764
1868
|
var hasSameFormOwner = ($input.form === $inputWithSameName.form);
|
1765
1869
|
if (hasSameFormOwner && $inputWithSameName !== $input) {
|
1766
1870
|
$inputWithSameName.checked = false;
|
1871
|
+
this.syncConditionalRevealWithInputState($inputWithSameName);
|
1767
1872
|
}
|
1768
|
-
});
|
1769
|
-
|
1770
|
-
this.syncAllConditionalReveals();
|
1873
|
+
}.bind(this));
|
1771
1874
|
};
|
1772
1875
|
|
1773
1876
|
/**
|
@@ -1786,10 +1889,9 @@ Checkboxes.prototype.unCheckExclusiveInputs = function ($input) {
|
|
1786
1889
|
var hasSameFormOwner = ($input.form === $exclusiveInput.form);
|
1787
1890
|
if (hasSameFormOwner) {
|
1788
1891
|
$exclusiveInput.checked = false;
|
1892
|
+
this.syncConditionalRevealWithInputState($exclusiveInput);
|
1789
1893
|
}
|
1790
|
-
});
|
1791
|
-
|
1792
|
-
this.syncAllConditionalReveals();
|
1894
|
+
}.bind(this));
|
1793
1895
|
};
|
1794
1896
|
|
1795
1897
|
/**
|
@@ -2088,7 +2190,7 @@ Header.prototype.init = function () {
|
|
2088
2190
|
return
|
2089
2191
|
}
|
2090
2192
|
|
2091
|
-
this.syncState(this.$menu.classList.contains('govuk-header__navigation--open'));
|
2193
|
+
this.syncState(this.$menu.classList.contains('govuk-header__navigation-list--open'));
|
2092
2194
|
this.$menuButton.addEventListener('click', this.handleMenuButtonClick.bind(this));
|
2093
2195
|
};
|
2094
2196
|
|
@@ -2112,7 +2214,7 @@ Header.prototype.syncState = function (isVisible) {
|
|
2112
2214
|
* sync the accessibility state and menu button state
|
2113
2215
|
*/
|
2114
2216
|
Header.prototype.handleMenuButtonClick = function () {
|
2115
|
-
var isVisible = this.$menu.classList.toggle('govuk-header__navigation--open');
|
2217
|
+
var isVisible = this.$menu.classList.toggle('govuk-header__navigation-list--open');
|
2116
2218
|
this.syncState(isVisible);
|
2117
2219
|
};
|
2118
2220
|
|
@@ -2144,7 +2246,7 @@ Radios.prototype.init = function () {
|
|
2144
2246
|
|
2145
2247
|
// Skip radios without data-aria-controls attributes, or where the
|
2146
2248
|
// target element does not exist.
|
2147
|
-
if (!target ||
|
2249
|
+
if (!target || !document.getElementById(target)) {
|
2148
2250
|
return
|
2149
2251
|
}
|
2150
2252
|
|
@@ -2189,7 +2291,7 @@ Radios.prototype.syncAllConditionalReveals = function () {
|
|
2189
2291
|
* @param {HTMLInputElement} $input Radio input
|
2190
2292
|
*/
|
2191
2293
|
Radios.prototype.syncConditionalRevealWithInputState = function ($input) {
|
2192
|
-
var $target = document.
|
2294
|
+
var $target = document.getElementById($input.getAttribute('aria-controls'));
|
2193
2295
|
|
2194
2296
|
if ($target && $target.classList.contains('govuk-radios__conditional')) {
|
2195
2297
|
var inputIsChecked = $input.checked;
|
@@ -2231,6 +2333,95 @@ Radios.prototype.handleClick = function (event) {
|
|
2231
2333
|
}.bind(this));
|
2232
2334
|
};
|
2233
2335
|
|
2336
|
+
function SkipLink ($module) {
|
2337
|
+
this.$module = $module;
|
2338
|
+
this.$linkedElement = null;
|
2339
|
+
this.linkedElementListener = false;
|
2340
|
+
}
|
2341
|
+
|
2342
|
+
/**
|
2343
|
+
* Initialise the component
|
2344
|
+
*/
|
2345
|
+
SkipLink.prototype.init = function () {
|
2346
|
+
// Check for module
|
2347
|
+
if (!this.$module) {
|
2348
|
+
return
|
2349
|
+
}
|
2350
|
+
|
2351
|
+
// Check for linked element
|
2352
|
+
this.$linkedElement = this.getLinkedElement();
|
2353
|
+
if (!this.$linkedElement) {
|
2354
|
+
return
|
2355
|
+
}
|
2356
|
+
|
2357
|
+
this.$module.addEventListener('click', this.focusLinkedElement.bind(this));
|
2358
|
+
};
|
2359
|
+
|
2360
|
+
/**
|
2361
|
+
* Get linked element
|
2362
|
+
*
|
2363
|
+
* @returns {HTMLElement} $linkedElement - DOM element linked to from the skip link
|
2364
|
+
*/
|
2365
|
+
SkipLink.prototype.getLinkedElement = function () {
|
2366
|
+
var linkedElementId = this.getFragmentFromUrl();
|
2367
|
+
|
2368
|
+
if (!linkedElementId) {
|
2369
|
+
return false
|
2370
|
+
}
|
2371
|
+
|
2372
|
+
return document.getElementById(linkedElementId)
|
2373
|
+
};
|
2374
|
+
|
2375
|
+
/**
|
2376
|
+
* Focus the linked element
|
2377
|
+
*
|
2378
|
+
* Set tabindex and helper CSS class. Set listener to remove them on blur.
|
2379
|
+
*/
|
2380
|
+
SkipLink.prototype.focusLinkedElement = function () {
|
2381
|
+
var $linkedElement = this.$linkedElement;
|
2382
|
+
|
2383
|
+
if (!$linkedElement.getAttribute('tabindex')) {
|
2384
|
+
// Set the element tabindex to -1 so it can be focused with JavaScript.
|
2385
|
+
$linkedElement.setAttribute('tabindex', '-1');
|
2386
|
+
$linkedElement.classList.add('govuk-skip-link-focused-element');
|
2387
|
+
|
2388
|
+
// Add listener for blur on the focused element (unless the listener has previously been added)
|
2389
|
+
if (!this.linkedElementListener) {
|
2390
|
+
this.$linkedElement.addEventListener('blur', this.removeFocusProperties.bind(this));
|
2391
|
+
this.linkedElementListener = true;
|
2392
|
+
}
|
2393
|
+
}
|
2394
|
+
$linkedElement.focus();
|
2395
|
+
};
|
2396
|
+
|
2397
|
+
/**
|
2398
|
+
* Remove the tabindex that makes the linked element focusable because the element only needs to be
|
2399
|
+
* focusable until it has received programmatic focus and a screen reader has announced it.
|
2400
|
+
*
|
2401
|
+
* Remove the CSS class that removes the native focus styles.
|
2402
|
+
*/
|
2403
|
+
SkipLink.prototype.removeFocusProperties = function () {
|
2404
|
+
this.$linkedElement.removeAttribute('tabindex');
|
2405
|
+
this.$linkedElement.classList.remove('govuk-skip-link-focused-element');
|
2406
|
+
};
|
2407
|
+
|
2408
|
+
/**
|
2409
|
+
* Get fragment from URL
|
2410
|
+
*
|
2411
|
+
* Extract the fragment (everything after the hash symbol) from a URL, but not including
|
2412
|
+
* the symbol.
|
2413
|
+
*
|
2414
|
+
* @returns {string} Fragment from URL, without the hash symbol
|
2415
|
+
*/
|
2416
|
+
SkipLink.prototype.getFragmentFromUrl = function () {
|
2417
|
+
// Bail if the anchor link doesn't have a hash
|
2418
|
+
if (!this.$module.hash) {
|
2419
|
+
return false
|
2420
|
+
}
|
2421
|
+
|
2422
|
+
return this.$module.hash.split('#').pop()
|
2423
|
+
};
|
2424
|
+
|
2234
2425
|
(function(undefined) {
|
2235
2426
|
|
2236
2427
|
// Detection from https://raw.githubusercontent.com/Financial-Times/polyfill-library/master/polyfills/Element/prototype/nextElementSibling/detect.js
|
@@ -2596,6 +2787,10 @@ function initAll (options) {
|
|
2596
2787
|
new Radios($radio).init();
|
2597
2788
|
});
|
2598
2789
|
|
2790
|
+
// Find first skip link module to enhance.
|
2791
|
+
var $skipLink = scope.querySelector('[data-module="govuk-skip-link"]');
|
2792
|
+
new SkipLink($skipLink).init();
|
2793
|
+
|
2599
2794
|
var $tabs = scope.querySelectorAll('[data-module="govuk-tabs"]');
|
2600
2795
|
nodeListForEach($tabs, function ($tabs) {
|
2601
2796
|
new Tabs($tabs).init();
|
@@ -2610,7 +2805,9 @@ exports.CharacterCount = CharacterCount;
|
|
2610
2805
|
exports.Checkboxes = Checkboxes;
|
2611
2806
|
exports.ErrorSummary = ErrorSummary;
|
2612
2807
|
exports.Header = Header;
|
2808
|
+
exports.NotificationBanner = NotificationBanner;
|
2613
2809
|
exports.Radios = Radios;
|
2810
|
+
exports.SkipLink = SkipLink;
|
2614
2811
|
exports.Tabs = Tabs;
|
2615
2812
|
|
2616
2813
|
})));
|