govuk_publishing_components 34.7.0 → 34.7.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.
- checksums.yaml +4 -4
- data/lib/govuk_publishing_components/presenters/related_navigation_helper.rb +0 -7
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/govuk-frontend/govuk/all.js +4029 -3792
- data/node_modules/govuk-frontend/govuk/all.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/common/closest-attribute-value.js +52 -51
- data/node_modules/govuk-frontend/govuk/common/closest-attribute-value.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/common/index.js +153 -145
- data/node_modules/govuk-frontend/govuk/common/index.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/common/normalise-dataset.js +324 -321
- data/node_modules/govuk-frontend/govuk/common/normalise-dataset.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/common.js +154 -146
- data/node_modules/govuk-frontend/govuk/common.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/_all.scss +1 -1
- data/node_modules/govuk-frontend/govuk/components/accordion/_index.scss +23 -4
- data/node_modules/govuk-frontend/govuk/components/accordion/accordion.js +2059 -1654
- data/node_modules/govuk-frontend/govuk/components/accordion/accordion.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/accordion/fixtures.json +11 -11
- data/node_modules/govuk-frontend/govuk/components/accordion/template.njk +1 -1
- data/node_modules/govuk-frontend/govuk/components/back-link/_index.scss +19 -19
- data/node_modules/govuk-frontend/govuk/components/breadcrumbs/_index.scss +21 -10
- data/node_modules/govuk-frontend/govuk/components/button/button.js +927 -917
- data/node_modules/govuk-frontend/govuk/components/button/button.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/character-count/character-count.js +2050 -2040
- data/node_modules/govuk-frontend/govuk/components/character-count/character-count.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/checkboxes/checkboxes.js +1155 -1147
- data/node_modules/govuk-frontend/govuk/components/checkboxes/checkboxes.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/cookie-banner/fixtures.json +23 -23
- data/node_modules/govuk-frontend/govuk/components/cookie-banner/template.njk +1 -1
- data/node_modules/govuk-frontend/govuk/components/details/details.js +800 -799
- data/node_modules/govuk-frontend/govuk/components/details/details.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/error-summary/error-summary.js +1058 -1045
- data/node_modules/govuk-frontend/govuk/components/error-summary/error-summary.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/header/_index.scss +6 -0
- data/node_modules/govuk-frontend/govuk/components/header/header.js +646 -998
- data/node_modules/govuk-frontend/govuk/components/header/header.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/notification-banner/notification-banner.js +760 -752
- data/node_modules/govuk-frontend/govuk/components/notification-banner/notification-banner.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/pagination/fixtures.json +61 -0
- data/node_modules/govuk-frontend/govuk/components/pagination/template.njk +1 -1
- data/node_modules/govuk-frontend/govuk/components/phase-banner/macro-options.json +1 -1
- data/node_modules/govuk-frontend/govuk/components/radios/radios.js +1110 -1107
- data/node_modules/govuk-frontend/govuk/components/radios/radios.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/skip-link/skip-link.js +1017 -1014
- data/node_modules/govuk-frontend/govuk/components/skip-link/skip-link.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/summary-list/_index.scss +107 -0
- data/node_modules/govuk-frontend/govuk/components/summary-list/fixtures.json +318 -23
- data/node_modules/govuk-frontend/govuk/components/summary-list/macro-options.json +110 -0
- data/node_modules/govuk-frontend/govuk/components/summary-list/template.njk +72 -28
- data/node_modules/govuk-frontend/govuk/components/tabs/tabs.js +1392 -1264
- data/node_modules/govuk-frontend/govuk/components/tabs/tabs.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/i18n.js +363 -364
- data/node_modules/govuk-frontend/govuk/i18n.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/settings/_measurements.scss +5 -5
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/DOMTokenList.js +242 -241
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/DOMTokenList.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Date/now.js +13 -12
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Date/now.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Document.js +17 -16
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Document.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/classList.js +547 -546
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/classList.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/closest.js +37 -36
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/closest.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/dataset.js +251 -250
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/dataset.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/matches.js +21 -20
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/matches.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/nextElementSibling.js +198 -197
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/nextElementSibling.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/previousElementSibling.js +198 -197
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/previousElementSibling.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element.js +106 -105
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Event.js +400 -399
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Event.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Function/prototype/bind.js +239 -238
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Function/prototype/bind.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Object/defineProperty.js +72 -71
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Object/defineProperty.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/String/prototype/trim.js +14 -13
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/String/prototype/trim.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Window.js +17 -16
- data/node_modules/govuk-frontend/govuk/vendor/polyfills/Window.js.map +1 -0
- data/node_modules/govuk-frontend/govuk-esm/all.mjs +2 -2
- data/node_modules/govuk-frontend/govuk-esm/common/index.mjs +17 -10
- data/node_modules/govuk-frontend/govuk-esm/common/normalise-dataset.mjs +3 -1
- data/node_modules/govuk-frontend/govuk-esm/components/accordion/accordion.mjs +135 -52
- data/node_modules/govuk-frontend/govuk-esm/components/button/button.mjs +11 -9
- data/node_modules/govuk-frontend/govuk-esm/components/character-count/character-count.mjs +10 -7
- data/node_modules/govuk-frontend/govuk-esm/components/checkboxes/checkboxes.mjs +24 -18
- data/node_modules/govuk-frontend/govuk-esm/components/details/details.mjs +23 -16
- data/node_modules/govuk-frontend/govuk-esm/components/error-summary/error-summary.mjs +15 -11
- data/node_modules/govuk-frontend/govuk-esm/components/header/header.mjs +3 -2
- data/node_modules/govuk-frontend/govuk-esm/components/notification-banner/notification-banner.mjs +3 -4
- data/node_modules/govuk-frontend/govuk-esm/components/radios/radios.mjs +10 -9
- data/node_modules/govuk-frontend/govuk-esm/components/skip-link/skip-link.mjs +5 -3
- data/node_modules/govuk-frontend/govuk-esm/components/tabs/tabs.mjs +165 -38
- data/node_modules/govuk-frontend/govuk-esm/i18n.mjs +9 -11
- data/node_modules/govuk-frontend/package.json +1 -1
- metadata +34 -2
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
/* eslint-disable es-x/no-function-prototype-bind -- Polyfill imported */
|
|
2
|
+
/* eslint-disable es-x/no-string-prototype-trim -- Polyfill imported */
|
|
3
|
+
|
|
1
4
|
import { nodeListForEach, mergeConfigs, extractConfigByNamespace } from '../../common/index.mjs'
|
|
5
|
+
import { normaliseDataset } from '../../common/normalise-dataset.mjs'
|
|
2
6
|
import { I18n } from '../../i18n.mjs'
|
|
3
|
-
import '../../vendor/polyfills/Function/prototype/bind.mjs'
|
|
4
7
|
import '../../vendor/polyfills/Element/prototype/classList.mjs'
|
|
8
|
+
import '../../vendor/polyfills/Element/prototype/closest.mjs'
|
|
9
|
+
import '../../vendor/polyfills/Event.mjs' // addEventListener, event.target normalization and DOMContentLoaded
|
|
10
|
+
import '../../vendor/polyfills/Function/prototype/bind.mjs'
|
|
5
11
|
import '../../vendor/polyfills/String/prototype/trim.mjs'
|
|
6
|
-
import { normaliseDataset } from '../../common/normalise-dataset.mjs'
|
|
7
12
|
|
|
8
13
|
/**
|
|
9
14
|
* @constant
|
|
@@ -38,27 +43,29 @@ var ACCORDION_TRANSLATIONS = {
|
|
|
38
43
|
*/
|
|
39
44
|
function Accordion ($module, config) {
|
|
40
45
|
this.$module = $module
|
|
41
|
-
this.$sections = $module.querySelectorAll('.govuk-accordion__section')
|
|
42
|
-
this.browserSupportsSessionStorage = helper.checkForSessionStorage()
|
|
43
46
|
|
|
44
47
|
var defaultConfig = {
|
|
45
48
|
i18n: ACCORDION_TRANSLATIONS
|
|
46
49
|
}
|
|
50
|
+
|
|
47
51
|
this.config = mergeConfigs(
|
|
48
52
|
defaultConfig,
|
|
49
53
|
config || {},
|
|
50
54
|
normaliseDataset($module.dataset)
|
|
51
55
|
)
|
|
56
|
+
|
|
52
57
|
this.i18n = new I18n(extractConfigByNamespace(this.config, 'i18n'))
|
|
53
58
|
|
|
54
59
|
this.controlsClass = 'govuk-accordion__controls'
|
|
55
60
|
this.showAllClass = 'govuk-accordion__show-all'
|
|
56
61
|
this.showAllTextClass = 'govuk-accordion__show-all-text'
|
|
57
62
|
|
|
63
|
+
this.sectionClass = 'govuk-accordion__section'
|
|
58
64
|
this.sectionExpandedClass = 'govuk-accordion__section--expanded'
|
|
59
65
|
this.sectionButtonClass = 'govuk-accordion__section-button'
|
|
60
66
|
this.sectionHeaderClass = 'govuk-accordion__section-header'
|
|
61
67
|
this.sectionHeadingClass = 'govuk-accordion__section-heading'
|
|
68
|
+
this.sectionHeadingDividerClass = 'govuk-accordion__section-heading-divider'
|
|
62
69
|
this.sectionHeadingTextClass = 'govuk-accordion__section-heading-text'
|
|
63
70
|
this.sectionHeadingTextFocusClass = 'govuk-accordion__section-heading-text-focus'
|
|
64
71
|
|
|
@@ -70,9 +77,15 @@ function Accordion ($module, config) {
|
|
|
70
77
|
|
|
71
78
|
this.sectionSummaryClass = 'govuk-accordion__section-summary'
|
|
72
79
|
this.sectionSummaryFocusClass = 'govuk-accordion__section-summary-focus'
|
|
80
|
+
this.sectionContentClass = 'govuk-accordion__section-content'
|
|
81
|
+
|
|
82
|
+
this.$sections = this.$module.querySelectorAll('.' + this.sectionClass)
|
|
83
|
+
this.browserSupportsSessionStorage = helper.checkForSessionStorage()
|
|
73
84
|
}
|
|
74
85
|
|
|
75
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Initialise component
|
|
88
|
+
*/
|
|
76
89
|
Accordion.prototype.init = function () {
|
|
77
90
|
// Check for module
|
|
78
91
|
if (!this.$module) {
|
|
@@ -87,7 +100,9 @@ Accordion.prototype.init = function () {
|
|
|
87
100
|
this.updateShowAllButton(areAllSectionsOpen)
|
|
88
101
|
}
|
|
89
102
|
|
|
90
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Initialise controls and set attributes
|
|
105
|
+
*/
|
|
91
106
|
Accordion.prototype.initControls = function () {
|
|
92
107
|
// Create "Show all" button and set attributes
|
|
93
108
|
this.$showAllButton = document.createElement('button')
|
|
@@ -96,9 +111,9 @@ Accordion.prototype.initControls = function () {
|
|
|
96
111
|
this.$showAllButton.setAttribute('aria-expanded', 'false')
|
|
97
112
|
|
|
98
113
|
// Create icon, add to element
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
this.$showAllButton.appendChild(
|
|
114
|
+
this.$showAllIcon = document.createElement('span')
|
|
115
|
+
this.$showAllIcon.classList.add(this.upChevronIconClass)
|
|
116
|
+
this.$showAllButton.appendChild(this.$showAllIcon)
|
|
102
117
|
|
|
103
118
|
// Create control wrapper and add controls to it
|
|
104
119
|
var $accordionControls = document.createElement('div')
|
|
@@ -107,15 +122,22 @@ Accordion.prototype.initControls = function () {
|
|
|
107
122
|
this.$module.insertBefore($accordionControls, this.$module.firstChild)
|
|
108
123
|
|
|
109
124
|
// Build additional wrapper for Show all toggle text and place after icon
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
this.$showAllButton.appendChild(
|
|
125
|
+
this.$showAllText = document.createElement('span')
|
|
126
|
+
this.$showAllText.classList.add(this.showAllTextClass)
|
|
127
|
+
this.$showAllButton.appendChild(this.$showAllText)
|
|
113
128
|
|
|
114
129
|
// Handle click events on the show/hide all button
|
|
115
130
|
this.$showAllButton.addEventListener('click', this.onShowOrHideAllToggle.bind(this))
|
|
131
|
+
|
|
132
|
+
// Handle 'beforematch' events, if the user agent supports them
|
|
133
|
+
if ('onbeforematch' in document) {
|
|
134
|
+
document.addEventListener('beforematch', this.onBeforeMatch.bind(this))
|
|
135
|
+
}
|
|
116
136
|
}
|
|
117
137
|
|
|
118
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Initialise section headers
|
|
140
|
+
*/
|
|
119
141
|
Accordion.prototype.initSectionHeaders = function () {
|
|
120
142
|
// Loop through section headers
|
|
121
143
|
nodeListForEach(this.$sections, function ($section, i) {
|
|
@@ -133,10 +155,16 @@ Accordion.prototype.initSectionHeaders = function () {
|
|
|
133
155
|
}.bind(this))
|
|
134
156
|
}
|
|
135
157
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Construct section header
|
|
160
|
+
*
|
|
161
|
+
* @param {HTMLDivElement} $header - Section header
|
|
162
|
+
* @param {number} index - Section index
|
|
163
|
+
*/
|
|
164
|
+
Accordion.prototype.constructHeaderMarkup = function ($header, index) {
|
|
165
|
+
var $span = $header.querySelector('.' + this.sectionButtonClass)
|
|
166
|
+
var $heading = $header.querySelector('.' + this.sectionHeadingClass)
|
|
167
|
+
var $summary = $header.querySelector('.' + this.sectionSummaryClass)
|
|
140
168
|
|
|
141
169
|
// Create a button element that will replace the '.govuk-accordion__section-button' span
|
|
142
170
|
var $button = document.createElement('button')
|
|
@@ -168,23 +196,23 @@ Accordion.prototype.constructHeaderMarkup = function ($headerWrapper, index) {
|
|
|
168
196
|
$headingTextFocus.innerHTML = $span.innerHTML
|
|
169
197
|
|
|
170
198
|
// Create container for show / hide icons and text.
|
|
171
|
-
var $
|
|
172
|
-
$
|
|
199
|
+
var $showHideToggle = document.createElement('span')
|
|
200
|
+
$showHideToggle.classList.add(this.sectionShowHideToggleClass)
|
|
173
201
|
// Tell Google not to index the 'show' text as part of the heading
|
|
174
202
|
// For the snippet to work with JavaScript, it must be added before adding the page element to the
|
|
175
203
|
// page's DOM. See https://developers.google.com/search/docs/advanced/robots/robots_meta_tag#data-nosnippet-attr
|
|
176
|
-
$
|
|
204
|
+
$showHideToggle.setAttribute('data-nosnippet', '')
|
|
177
205
|
// Create an inner container to limit the width of the focus state
|
|
178
|
-
var $
|
|
179
|
-
$
|
|
180
|
-
$
|
|
206
|
+
var $showHideToggleFocus = document.createElement('span')
|
|
207
|
+
$showHideToggleFocus.classList.add(this.sectionShowHideToggleFocusClass)
|
|
208
|
+
$showHideToggle.appendChild($showHideToggleFocus)
|
|
181
209
|
// Create wrapper for the show / hide text. Append text after the show/hide icon
|
|
182
|
-
var $
|
|
183
|
-
var $
|
|
184
|
-
$
|
|
185
|
-
$
|
|
186
|
-
$
|
|
187
|
-
$
|
|
210
|
+
var $showHideText = document.createElement('span')
|
|
211
|
+
var $showHideIcon = document.createElement('span')
|
|
212
|
+
$showHideIcon.classList.add(this.upChevronIconClass)
|
|
213
|
+
$showHideToggleFocus.appendChild($showHideIcon)
|
|
214
|
+
$showHideText.classList.add(this.sectionShowHideTextClass)
|
|
215
|
+
$showHideToggleFocus.appendChild($showHideText)
|
|
188
216
|
|
|
189
217
|
// Append elements to the button:
|
|
190
218
|
// 1. Heading text
|
|
@@ -223,13 +251,29 @@ Accordion.prototype.constructHeaderMarkup = function ($headerWrapper, index) {
|
|
|
223
251
|
$button.appendChild(this.getButtonPunctuationEl())
|
|
224
252
|
}
|
|
225
253
|
|
|
226
|
-
$button.appendChild($
|
|
254
|
+
$button.appendChild($showHideToggle)
|
|
227
255
|
|
|
228
256
|
$heading.removeChild($span)
|
|
229
257
|
$heading.appendChild($button)
|
|
230
258
|
}
|
|
231
259
|
|
|
232
|
-
|
|
260
|
+
/**
|
|
261
|
+
* When a section is opened by the user agent via the 'beforematch' event
|
|
262
|
+
*
|
|
263
|
+
* @param {Event} event - Generic event
|
|
264
|
+
*/
|
|
265
|
+
Accordion.prototype.onBeforeMatch = function (event) {
|
|
266
|
+
var $section = event.target.closest('.' + this.sectionClass)
|
|
267
|
+
if ($section) {
|
|
268
|
+
this.setExpanded(true, $section)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* When section toggled, set and store state
|
|
274
|
+
*
|
|
275
|
+
* @param {HTMLElement} $section - Section element
|
|
276
|
+
*/
|
|
233
277
|
Accordion.prototype.onSectionToggle = function ($section) {
|
|
234
278
|
var expanded = this.isExpanded($section)
|
|
235
279
|
this.setExpanded(!expanded, $section)
|
|
@@ -238,7 +282,9 @@ Accordion.prototype.onSectionToggle = function ($section) {
|
|
|
238
282
|
this.storeState($section)
|
|
239
283
|
}
|
|
240
284
|
|
|
241
|
-
|
|
285
|
+
/**
|
|
286
|
+
* When Open/Close All toggled, set and store state
|
|
287
|
+
*/
|
|
242
288
|
Accordion.prototype.onShowOrHideAllToggle = function () {
|
|
243
289
|
var $module = this
|
|
244
290
|
var $sections = this.$sections
|
|
@@ -253,11 +299,18 @@ Accordion.prototype.onShowOrHideAllToggle = function () {
|
|
|
253
299
|
$module.updateShowAllButton(nowExpanded)
|
|
254
300
|
}
|
|
255
301
|
|
|
256
|
-
|
|
302
|
+
/**
|
|
303
|
+
* Set section attributes when opened/closed
|
|
304
|
+
*
|
|
305
|
+
* @param {boolean} expanded - Section expanded
|
|
306
|
+
* @param {HTMLElement} $section - Section element
|
|
307
|
+
*/
|
|
257
308
|
Accordion.prototype.setExpanded = function (expanded, $section) {
|
|
258
|
-
var $
|
|
309
|
+
var $showHideIcon = $section.querySelector('.' + this.upChevronIconClass)
|
|
259
310
|
var $showHideText = $section.querySelector('.' + this.sectionShowHideTextClass)
|
|
260
311
|
var $button = $section.querySelector('.' + this.sectionButtonClass)
|
|
312
|
+
var $content = $section.querySelector('.' + this.sectionContentClass)
|
|
313
|
+
|
|
261
314
|
var newButtonText = expanded
|
|
262
315
|
? this.i18n.t('hideSection')
|
|
263
316
|
: this.i18n.t('showSection')
|
|
@@ -266,8 +319,12 @@ Accordion.prototype.setExpanded = function (expanded, $section) {
|
|
|
266
319
|
$button.setAttribute('aria-expanded', expanded)
|
|
267
320
|
|
|
268
321
|
// Update aria-label combining
|
|
269
|
-
var
|
|
270
|
-
|
|
322
|
+
var ariaLabelParts = []
|
|
323
|
+
|
|
324
|
+
var $headingText = $section.querySelector('.' + this.sectionHeadingTextClass)
|
|
325
|
+
if ($headingText) {
|
|
326
|
+
ariaLabelParts.push($headingText.innerText.trim())
|
|
327
|
+
}
|
|
271
328
|
|
|
272
329
|
var $summary = $section.querySelector('.' + this.sectionSummaryClass)
|
|
273
330
|
if ($summary) {
|
|
@@ -288,11 +345,13 @@ Accordion.prototype.setExpanded = function (expanded, $section) {
|
|
|
288
345
|
|
|
289
346
|
// Swap icon, change class
|
|
290
347
|
if (expanded) {
|
|
348
|
+
$content.removeAttribute('hidden')
|
|
291
349
|
$section.classList.add(this.sectionExpandedClass)
|
|
292
|
-
$
|
|
350
|
+
$showHideIcon.classList.remove(this.downChevronIconClass)
|
|
293
351
|
} else {
|
|
352
|
+
$content.setAttribute('hidden', 'until-found')
|
|
294
353
|
$section.classList.remove(this.sectionExpandedClass)
|
|
295
|
-
$
|
|
354
|
+
$showHideIcon.classList.add(this.downChevronIconClass)
|
|
296
355
|
}
|
|
297
356
|
|
|
298
357
|
// See if "Show all sections" button text should be updated
|
|
@@ -300,12 +359,21 @@ Accordion.prototype.setExpanded = function (expanded, $section) {
|
|
|
300
359
|
this.updateShowAllButton(areAllSectionsOpen)
|
|
301
360
|
}
|
|
302
361
|
|
|
303
|
-
|
|
362
|
+
/**
|
|
363
|
+
* Get state of section
|
|
364
|
+
*
|
|
365
|
+
* @param {HTMLElement} $section - Section element
|
|
366
|
+
* @returns {boolean} True if expanded
|
|
367
|
+
*/
|
|
304
368
|
Accordion.prototype.isExpanded = function ($section) {
|
|
305
369
|
return $section.classList.contains(this.sectionExpandedClass)
|
|
306
370
|
}
|
|
307
371
|
|
|
308
|
-
|
|
372
|
+
/**
|
|
373
|
+
* Check if all sections are open
|
|
374
|
+
*
|
|
375
|
+
* @returns {boolean} True if all sections are open
|
|
376
|
+
*/
|
|
309
377
|
Accordion.prototype.checkIfAllSectionsOpen = function () {
|
|
310
378
|
// Get a count of all the Accordion sections
|
|
311
379
|
var sectionsCount = this.$sections.length
|
|
@@ -316,26 +384,33 @@ Accordion.prototype.checkIfAllSectionsOpen = function () {
|
|
|
316
384
|
return areAllSectionsOpen
|
|
317
385
|
}
|
|
318
386
|
|
|
319
|
-
|
|
387
|
+
/**
|
|
388
|
+
* Update "Show all sections" button
|
|
389
|
+
*
|
|
390
|
+
* @param {boolean} expanded - Section expanded
|
|
391
|
+
*/
|
|
320
392
|
Accordion.prototype.updateShowAllButton = function (expanded) {
|
|
321
|
-
var $showAllIcon = this.$showAllButton.querySelector('.' + this.upChevronIconClass)
|
|
322
|
-
var $showAllText = this.$showAllButton.querySelector('.' + this.showAllTextClass)
|
|
323
393
|
var newButtonText = expanded
|
|
324
394
|
? this.i18n.t('hideAllSections')
|
|
325
395
|
: this.i18n.t('showAllSections')
|
|
396
|
+
|
|
326
397
|
this.$showAllButton.setAttribute('aria-expanded', expanded)
|
|
327
|
-
|
|
398
|
+
this.$showAllText.innerText = newButtonText
|
|
328
399
|
|
|
329
400
|
// Swap icon, toggle class
|
|
330
401
|
if (expanded) {
|
|
331
|
-
|
|
402
|
+
this.$showAllIcon.classList.remove(this.downChevronIconClass)
|
|
332
403
|
} else {
|
|
333
|
-
|
|
404
|
+
this.$showAllIcon.classList.add(this.downChevronIconClass)
|
|
334
405
|
}
|
|
335
406
|
}
|
|
336
407
|
|
|
337
|
-
// Check for `window.sessionStorage`, and that it actually works.
|
|
338
408
|
var helper = {
|
|
409
|
+
/**
|
|
410
|
+
* Check for `window.sessionStorage`, and that it actually works.
|
|
411
|
+
*
|
|
412
|
+
* @returns {boolean} True if session storage is available
|
|
413
|
+
*/
|
|
339
414
|
checkForSessionStorage: function () {
|
|
340
415
|
var testString = 'this is the test string'
|
|
341
416
|
var result
|
|
@@ -350,7 +425,11 @@ var helper = {
|
|
|
350
425
|
}
|
|
351
426
|
}
|
|
352
427
|
|
|
353
|
-
|
|
428
|
+
/**
|
|
429
|
+
* Set the state of the accordions in sessionStorage
|
|
430
|
+
*
|
|
431
|
+
* @param {HTMLElement} $section - Section element
|
|
432
|
+
*/
|
|
354
433
|
Accordion.prototype.storeState = function ($section) {
|
|
355
434
|
if (this.browserSupportsSessionStorage) {
|
|
356
435
|
// We need a unique way of identifying each content in the Accordion. Since
|
|
@@ -370,7 +449,11 @@ Accordion.prototype.storeState = function ($section) {
|
|
|
370
449
|
}
|
|
371
450
|
}
|
|
372
451
|
|
|
373
|
-
|
|
452
|
+
/**
|
|
453
|
+
* Read the state of the accordions from sessionStorage
|
|
454
|
+
*
|
|
455
|
+
* @param {HTMLElement} $section - Section element
|
|
456
|
+
*/
|
|
374
457
|
Accordion.prototype.setInitialState = function ($section) {
|
|
375
458
|
if (this.browserSupportsSessionStorage) {
|
|
376
459
|
var $button = $section.querySelector('.' + this.sectionButtonClass)
|
|
@@ -389,15 +472,15 @@ Accordion.prototype.setInitialState = function ($section) {
|
|
|
389
472
|
/**
|
|
390
473
|
* Create an element to improve semantics of the section button with punctuation
|
|
391
474
|
*
|
|
392
|
-
* @returns {HTMLSpanElement} DOM element
|
|
393
|
-
*
|
|
394
475
|
* Adding punctuation to the button can also improve its general semantics by dividing its contents
|
|
395
476
|
* into thematic chunks.
|
|
396
477
|
* See https://github.com/alphagov/govuk-frontend/issues/2327#issuecomment-922957442
|
|
478
|
+
*
|
|
479
|
+
* @returns {HTMLElement} DOM element
|
|
397
480
|
*/
|
|
398
481
|
Accordion.prototype.getButtonPunctuationEl = function () {
|
|
399
482
|
var $punctuationEl = document.createElement('span')
|
|
400
|
-
$punctuationEl.classList.add('govuk-visually-hidden',
|
|
483
|
+
$punctuationEl.classList.add('govuk-visually-hidden', this.sectionHeadingDividerClass)
|
|
401
484
|
$punctuationEl.innerHTML = ', '
|
|
402
485
|
return $punctuationEl
|
|
403
486
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
/* eslint-disable es-x/no-function-prototype-bind -- Polyfill imported */
|
|
2
|
+
|
|
1
3
|
import { mergeConfigs } from '../../common/index.mjs'
|
|
2
4
|
import { normaliseDataset } from '../../common/normalise-dataset.mjs'
|
|
3
|
-
import '../../vendor/polyfills/Event.mjs' // addEventListener
|
|
5
|
+
import '../../vendor/polyfills/Event.mjs' // addEventListener, event.target normalization and DOMContentLoaded
|
|
4
6
|
import '../../vendor/polyfills/Function/prototype/bind.mjs'
|
|
5
7
|
|
|
6
8
|
var KEY_SPACE = 32
|
|
@@ -10,8 +12,8 @@ var DEBOUNCE_TIMEOUT_IN_SECONDS = 1
|
|
|
10
12
|
* JavaScript enhancements for the Button component
|
|
11
13
|
*
|
|
12
14
|
* @class
|
|
13
|
-
* @param {HTMLElement} $module -
|
|
14
|
-
* @param {ButtonConfig} config - Button config
|
|
15
|
+
* @param {HTMLElement} $module - HTML element to use for button
|
|
16
|
+
* @param {ButtonConfig} [config] - Button config
|
|
15
17
|
*/
|
|
16
18
|
function Button ($module, config) {
|
|
17
19
|
if (!$module) {
|
|
@@ -51,14 +53,14 @@ Button.prototype.init = function () {
|
|
|
51
53
|
*
|
|
52
54
|
* See https://github.com/alphagov/govuk_elements/pull/272#issuecomment-233028270
|
|
53
55
|
*
|
|
54
|
-
* @param {KeyboardEvent} event
|
|
56
|
+
* @param {KeyboardEvent} event - Keydown event
|
|
55
57
|
*/
|
|
56
58
|
Button.prototype.handleKeyDown = function (event) {
|
|
57
|
-
var target = event.target
|
|
59
|
+
var $target = event.target
|
|
58
60
|
|
|
59
|
-
if (target.getAttribute('role') === 'button' && event.keyCode === KEY_SPACE) {
|
|
61
|
+
if ($target.getAttribute('role') === 'button' && event.keyCode === KEY_SPACE) {
|
|
60
62
|
event.preventDefault() // prevent the page from scrolling
|
|
61
|
-
target.click()
|
|
63
|
+
$target.click()
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
|
|
@@ -69,8 +71,8 @@ Button.prototype.handleKeyDown = function (event) {
|
|
|
69
71
|
* stops people accidentally causing multiple form submissions by double
|
|
70
72
|
* clicking buttons.
|
|
71
73
|
*
|
|
72
|
-
* @param {MouseEvent} event
|
|
73
|
-
* @returns {undefined | false}
|
|
74
|
+
* @param {MouseEvent} event - Mouse click event
|
|
75
|
+
* @returns {undefined | false} Returns undefined, or false when debounced
|
|
74
76
|
*/
|
|
75
77
|
Button.prototype.debounce = function (event) {
|
|
76
78
|
// Check the button that was clicked has preventDoubleClick enabled
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import '../../
|
|
1
|
+
/* eslint-disable es-x/no-date-now -- Polyfill imported */
|
|
2
|
+
/* eslint-disable es-x/no-function-prototype-bind -- Polyfill imported */
|
|
3
|
+
|
|
4
|
+
import { closestAttributeValue } from '../../common/closest-attribute-value.mjs'
|
|
5
5
|
import { extractConfigByNamespace, mergeConfigs } from '../../common/index.mjs'
|
|
6
|
-
import { I18n } from '../../i18n.mjs'
|
|
7
6
|
import { normaliseDataset } from '../../common/normalise-dataset.mjs'
|
|
8
|
-
import {
|
|
7
|
+
import { I18n } from '../../i18n.mjs'
|
|
8
|
+
import '../../vendor/polyfills/Date/now.mjs'
|
|
9
|
+
import '../../vendor/polyfills/Element/prototype/classList.mjs'
|
|
10
|
+
import '../../vendor/polyfills/Event.mjs' // addEventListener, event.target normalization and DOMContentLoaded
|
|
11
|
+
import '../../vendor/polyfills/Function/prototype/bind.mjs'
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
14
|
* @constant
|
|
@@ -50,7 +53,7 @@ var CHARACTER_COUNT_TRANSLATIONS = {
|
|
|
50
53
|
* of the available characters/words has been entered.
|
|
51
54
|
*
|
|
52
55
|
* @class
|
|
53
|
-
* @param {HTMLElement} $module -
|
|
56
|
+
* @param {HTMLElement} $module - HTML element to use for character count
|
|
54
57
|
* @param {CharacterCountConfig} [config] - Character count config
|
|
55
58
|
*/
|
|
56
59
|
function CharacterCount ($module, config) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import '../../vendor/polyfills/Event.mjs'
|
|
4
|
-
import '../../vendor/polyfills/Element/prototype/classList.mjs'
|
|
1
|
+
/* eslint-disable es-x/no-function-prototype-bind -- Polyfill imported */
|
|
2
|
+
|
|
5
3
|
import { nodeListForEach } from '../../common/index.mjs'
|
|
4
|
+
import '../../vendor/polyfills/Element/prototype/classList.mjs'
|
|
5
|
+
import '../../vendor/polyfills/Event.mjs' // addEventListener, event.target normalization and DOMContentLoaded
|
|
6
|
+
import '../../vendor/polyfills/Function/prototype/bind.mjs'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Checkboxes component
|
|
@@ -16,7 +17,7 @@ function Checkboxes ($module) {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
|
-
* Initialise
|
|
20
|
+
* Initialise component
|
|
20
21
|
*
|
|
21
22
|
* Checkboxes can be associated with a 'conditionally revealed' content block –
|
|
22
23
|
* for example, a checkbox for 'Phone' could reveal an additional form field for
|
|
@@ -34,17 +35,17 @@ Checkboxes.prototype.init = function () {
|
|
|
34
35
|
var $inputs = this.$inputs
|
|
35
36
|
|
|
36
37
|
nodeListForEach($inputs, function ($input) {
|
|
37
|
-
var
|
|
38
|
+
var targetId = $input.getAttribute('data-aria-controls')
|
|
38
39
|
|
|
39
40
|
// Skip checkboxes without data-aria-controls attributes, or where the
|
|
40
41
|
// target element does not exist.
|
|
41
|
-
if (!
|
|
42
|
+
if (!targetId || !document.getElementById(targetId)) {
|
|
42
43
|
return
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
// Promote the data-aria-controls attribute to a aria-controls attribute
|
|
46
47
|
// so that the relationship is exposed in the AOM
|
|
47
|
-
$input.setAttribute('aria-controls',
|
|
48
|
+
$input.setAttribute('aria-controls', targetId)
|
|
48
49
|
$input.removeAttribute('data-aria-controls')
|
|
49
50
|
})
|
|
50
51
|
|
|
@@ -63,11 +64,12 @@ Checkboxes.prototype.init = function () {
|
|
|
63
64
|
// for example if they are added to the page dynamically, so sync now too.
|
|
64
65
|
this.syncAllConditionalReveals()
|
|
65
66
|
|
|
67
|
+
// Handle events
|
|
66
68
|
$module.addEventListener('click', this.handleClick.bind(this))
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
/**
|
|
70
|
-
* Sync the conditional reveal states for all
|
|
72
|
+
* Sync the conditional reveal states for all checkboxes in this $module.
|
|
71
73
|
*/
|
|
72
74
|
Checkboxes.prototype.syncAllConditionalReveals = function () {
|
|
73
75
|
nodeListForEach(this.$inputs, this.syncConditionalRevealWithInputState.bind(this))
|
|
@@ -97,6 +99,8 @@ Checkboxes.prototype.syncConditionalRevealWithInputState = function ($input) {
|
|
|
97
99
|
*
|
|
98
100
|
* Find any other checkbox inputs with the same name value, and uncheck them.
|
|
99
101
|
* This is useful for when a “None of these" checkbox is checked.
|
|
102
|
+
*
|
|
103
|
+
* @param {HTMLElement} $input - Checkbox input
|
|
100
104
|
*/
|
|
101
105
|
Checkboxes.prototype.unCheckAllInputsExcept = function ($input) {
|
|
102
106
|
var allInputsWithSameName = document.querySelectorAll('input[type="checkbox"][name="' + $input.name + '"]')
|
|
@@ -111,11 +115,13 @@ Checkboxes.prototype.unCheckAllInputsExcept = function ($input) {
|
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
/**
|
|
114
|
-
* Uncheck exclusive
|
|
118
|
+
* Uncheck exclusive checkboxes
|
|
115
119
|
*
|
|
116
120
|
* Find any checkbox inputs with the same name value and the 'exclusive' behaviour,
|
|
117
121
|
* and uncheck them. This helps prevent someone checking both a regular checkbox and a
|
|
118
122
|
* "None of these" checkbox in the same fieldset.
|
|
123
|
+
*
|
|
124
|
+
* @param {HTMLInputElement} $input - Checkbox input
|
|
119
125
|
*/
|
|
120
126
|
Checkboxes.prototype.unCheckExclusiveInputs = function ($input) {
|
|
121
127
|
var allInputsWithSameNameAndExclusiveBehaviour = document.querySelectorAll(
|
|
@@ -140,30 +146,30 @@ Checkboxes.prototype.unCheckExclusiveInputs = function ($input) {
|
|
|
140
146
|
* @param {MouseEvent} event - Click event
|
|
141
147
|
*/
|
|
142
148
|
Checkboxes.prototype.handleClick = function (event) {
|
|
143
|
-
var $
|
|
149
|
+
var $clickedInput = event.target
|
|
144
150
|
|
|
145
151
|
// Ignore clicks on things that aren't checkbox inputs
|
|
146
|
-
if ($
|
|
152
|
+
if ($clickedInput.type !== 'checkbox') {
|
|
147
153
|
return
|
|
148
154
|
}
|
|
149
155
|
|
|
150
156
|
// If the checkbox conditionally-reveals some content, sync the state
|
|
151
|
-
var hasAriaControls = $
|
|
157
|
+
var hasAriaControls = $clickedInput.getAttribute('aria-controls')
|
|
152
158
|
if (hasAriaControls) {
|
|
153
|
-
this.syncConditionalRevealWithInputState($
|
|
159
|
+
this.syncConditionalRevealWithInputState($clickedInput)
|
|
154
160
|
}
|
|
155
161
|
|
|
156
162
|
// No further behaviour needed for unchecking
|
|
157
|
-
if (!$
|
|
163
|
+
if (!$clickedInput.checked) {
|
|
158
164
|
return
|
|
159
165
|
}
|
|
160
166
|
|
|
161
167
|
// Handle 'exclusive' checkbox behaviour (ie "None of these")
|
|
162
|
-
var hasBehaviourExclusive = ($
|
|
168
|
+
var hasBehaviourExclusive = ($clickedInput.getAttribute('data-behaviour') === 'exclusive')
|
|
163
169
|
if (hasBehaviourExclusive) {
|
|
164
|
-
this.unCheckAllInputsExcept($
|
|
170
|
+
this.unCheckAllInputsExcept($clickedInput)
|
|
165
171
|
} else {
|
|
166
|
-
this.unCheckExclusiveInputs($
|
|
172
|
+
this.unCheckExclusiveInputs($clickedInput)
|
|
167
173
|
}
|
|
168
174
|
}
|
|
169
175
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
/* eslint-disable es-x/no-function-prototype-bind -- Polyfill imported */
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* JavaScript 'polyfill' for HTML5's <details> and <summary> elements
|
|
3
5
|
* and 'shim' to add accessiblity enhancements for all browsers
|
|
4
6
|
*
|
|
5
7
|
* http://caniuse.com/#feat=details
|
|
6
8
|
*/
|
|
7
|
-
import '../../vendor/polyfills/Function/prototype/bind.mjs'
|
|
8
|
-
import '../../vendor/polyfills/Event.mjs' // addEventListener and event.target normaliziation
|
|
9
9
|
import { generateUniqueID } from '../../common/index.mjs'
|
|
10
|
+
import '../../vendor/polyfills/Event.mjs' // addEventListener, event.target normalization and DOMContentLoaded
|
|
11
|
+
import '../../vendor/polyfills/Function/prototype/bind.mjs'
|
|
10
12
|
|
|
11
13
|
var KEY_ENTER = 13
|
|
12
14
|
var KEY_SPACE = 32
|
|
@@ -21,6 +23,9 @@ function Details ($module) {
|
|
|
21
23
|
this.$module = $module
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Initialise component
|
|
28
|
+
*/
|
|
24
29
|
Details.prototype.init = function () {
|
|
25
30
|
if (!this.$module) {
|
|
26
31
|
return
|
|
@@ -36,6 +41,9 @@ Details.prototype.init = function () {
|
|
|
36
41
|
this.polyfillDetails()
|
|
37
42
|
}
|
|
38
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Polyfill component in older browsers
|
|
46
|
+
*/
|
|
39
47
|
Details.prototype.polyfillDetails = function () {
|
|
40
48
|
var $module = this.$module
|
|
41
49
|
|
|
@@ -79,7 +87,7 @@ Details.prototype.polyfillDetails = function () {
|
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
// Bind an event to handle summary elements
|
|
82
|
-
this.polyfillHandleInputs(
|
|
90
|
+
this.polyfillHandleInputs(this.polyfillSetAttributes.bind(this))
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
/**
|
|
@@ -104,21 +112,20 @@ Details.prototype.polyfillSetAttributes = function () {
|
|
|
104
112
|
/**
|
|
105
113
|
* Handle cross-modal click events
|
|
106
114
|
*
|
|
107
|
-
* @param {object} node - element
|
|
108
115
|
* @param {polyfillHandleInputsCallback} callback - function
|
|
109
116
|
*/
|
|
110
|
-
Details.prototype.polyfillHandleInputs = function (
|
|
111
|
-
|
|
112
|
-
var target = event.target
|
|
117
|
+
Details.prototype.polyfillHandleInputs = function (callback) {
|
|
118
|
+
this.$summary.addEventListener('keypress', function (event) {
|
|
119
|
+
var $target = event.target
|
|
113
120
|
// When the key gets pressed - check if it is enter or space
|
|
114
121
|
if (event.keyCode === KEY_ENTER || event.keyCode === KEY_SPACE) {
|
|
115
|
-
if (target.nodeName.toLowerCase() === 'summary') {
|
|
122
|
+
if ($target.nodeName.toLowerCase() === 'summary') {
|
|
116
123
|
// Prevent space from scrolling the page
|
|
117
124
|
// and enter from submitting a form
|
|
118
125
|
event.preventDefault()
|
|
119
126
|
// Click to let the click event do all the necessary action
|
|
120
|
-
if (target.click) {
|
|
121
|
-
target.click()
|
|
127
|
+
if ($target.click) {
|
|
128
|
+
$target.click()
|
|
122
129
|
} else {
|
|
123
130
|
// except Safari 5.1 and under don't support .click() here
|
|
124
131
|
callback(event)
|
|
@@ -128,22 +135,22 @@ Details.prototype.polyfillHandleInputs = function (node, callback) {
|
|
|
128
135
|
})
|
|
129
136
|
|
|
130
137
|
// Prevent keyup to prevent clicking twice in Firefox when using space key
|
|
131
|
-
|
|
132
|
-
var target = event.target
|
|
138
|
+
this.$summary.addEventListener('keyup', function (event) {
|
|
139
|
+
var $target = event.target
|
|
133
140
|
if (event.keyCode === KEY_SPACE) {
|
|
134
|
-
if (target.nodeName.toLowerCase() === 'summary') {
|
|
141
|
+
if ($target.nodeName.toLowerCase() === 'summary') {
|
|
135
142
|
event.preventDefault()
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
145
|
})
|
|
139
146
|
|
|
140
|
-
|
|
147
|
+
this.$summary.addEventListener('click', callback)
|
|
141
148
|
}
|
|
142
149
|
|
|
143
150
|
export default Details
|
|
144
151
|
|
|
145
152
|
/**
|
|
146
153
|
* @callback polyfillHandleInputsCallback
|
|
147
|
-
* @param {
|
|
148
|
-
* @returns {
|
|
154
|
+
* @param {UIEvent} event - Keyboard or mouse event
|
|
155
|
+
* @returns {void}
|
|
149
156
|
*/
|