govuk_publishing_components 24.0.0 → 24.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aba99b9b513b88a9b3ac310bdca5299af17ff94d6c296a13e8087deb510ddf64
4
- data.tar.gz: 9238695c7fac3e53a47cda06d2de2114b7036dd805f9acba97dfc91c13151cdb
3
+ metadata.gz: 93a8bde02a39806e02cc9007a6b503aa3e65af3f1e7768b29f1d82c2c0ae66c4
4
+ data.tar.gz: b1e3bf6f8b98f5a4dcf2847fdca19aeed81b140491d43c230a5ea7074961d91b
5
5
  SHA512:
6
- metadata.gz: 8c39fe32ea761ab5d7a4c01752430b909c96947c3e8dfc9126071392a2ec10234f1948f1a4ca8724cb379c13ed712b361cf2de68f71263d4b80010043add2ba3
7
- data.tar.gz: 53e5a2d17340534140eedd509128853c27ea1c3633110c2039f7afd9f363fcbc3f152c73829cdd32a291867b655501f58b53a8a442bcb401dc4052073c7afb23
6
+ metadata.gz: 64cffb98c5dc002910a32ee736f21500ca921d5c3e5d165f66f87688d4e2a589da8e4aa69deba06b953924cf152aaac39e2f19752e80f7d7184285c9ce43bf8e
7
+ data.tar.gz: d1defc316e8d5e7171d903fa874ef1d8c93d416f1ce28e4c860aaed644b088e9621e24b2fb5a955768234a0d8d642193283509819348693b39c121e584aeeb5f
@@ -1,5 +1,287 @@
1
- // This component relies on JavaScript from GOV.UK Frontend
2
- // = require govuk/components/accordion/accordion.js
1
+ /* global nodeListForEach */
2
+ // = require ../vendor/polyfills/closest.js
3
+ // = require ../vendor/polyfills/indexOf.js
4
+ // = require ../vendor/polyfills/common.js
5
+
3
6
  window.GOVUK = window.GOVUK || {}
4
- window.GOVUK.Modules = window.GOVUK.Modules || {}
5
- window.GOVUK.Modules.Accordion = window.GOVUKFrontend
7
+ window.GOVUK.Modules = window.GOVUK.Modules || {};
8
+
9
+ (function (Modules) {
10
+ function GemAccordion () { }
11
+
12
+ GemAccordion.prototype.start = function ($module) {
13
+ this.$module = $module[0]
14
+ this.moduleId = this.$module.getAttribute('id')
15
+ this.sections = this.$module.querySelectorAll('.gem-c-accordion__section')
16
+ this.openAllButton = ''
17
+ this.browserSupportsSessionStorage = helper.checkForSessionStorage()
18
+ this.controlsClass = 'gem-c-accordion__controls'
19
+ this.openAllClass = 'gem-c-accordion__open-all'
20
+ this.openAllTextClass = 'gem-c-accordion__open-all-text'
21
+ this.sectionHeaderClass = 'gem-c-accordion__section-header'
22
+ this.sectionHeadingClass = 'gem-c-accordion__section-heading'
23
+ this.sectionSummaryClass = 'gem-c-accordion__section-summary'
24
+ this.sectionButtonClass = 'gem-c-accordion__section-button'
25
+ this.sectionExpandedClass = 'gem-c-accordion__section--expanded'
26
+ this.sectionInnerContent = 'gem-c-accordion__section-content'
27
+ this.toggleLinkClass = 'js-toggle-link'
28
+ this.sectionShowHideIconClass = 'gem-c-accordion__toggle-link'
29
+ this.sectionShowHideTextClass = 'gem-c-accordion__toggle-text'
30
+ this.upChevonIconClass = 'gem-c-accordion-nav__chevron'
31
+ this.downChevonIconClass = 'gem-c-accordion-nav__chevron--down'
32
+
33
+ // Indicate that js has worked
34
+ this.$module.classList.add('gem-c-accordion--active')
35
+
36
+ this.initControls()
37
+ this.initSectionHeaders()
38
+
39
+ // See if "Show all sections" button text should be updated
40
+ var areAllSectionsOpen = this.checkIfAllSectionsOpen()
41
+ this.updateOpenAllButton(areAllSectionsOpen)
42
+ }
43
+
44
+ // Initialise controls and set attributes
45
+ GemAccordion.prototype.initControls = function () {
46
+ // Create "Show all" button and set attributes
47
+ this.openAllButton = document.createElement('button')
48
+ this.openAllButton.setAttribute('class', this.openAllClass)
49
+ this.openAllButton.setAttribute('aria-expanded', 'false')
50
+
51
+ // Create icon, add to element
52
+ var icon = document.createElement('span')
53
+ icon.classList.add(this.upChevonIconClass)
54
+ this.openAllButton.appendChild(icon)
55
+
56
+ // Create control wrapper and add controls to it
57
+ var accordionControls = document.createElement('div')
58
+ accordionControls.setAttribute('class', this.controlsClass)
59
+ accordionControls.appendChild(this.openAllButton)
60
+ this.$module.insertBefore(accordionControls, this.$module.firstChild)
61
+
62
+ // Build addtional wrapper for open all toggle text, place icon after wrapped text.
63
+ var wrapperOpenAllText = document.createElement('span')
64
+ wrapperOpenAllText.classList.add(this.openAllTextClass)
65
+ this.openAllButton.insertBefore(wrapperOpenAllText, this.openAllButton.childNodes[0] || null)
66
+
67
+ // Handle events for the controls
68
+ this.openAllButton.addEventListener('click', this.onOpenOrCloseAllToggle.bind(this))
69
+ }
70
+
71
+ // Initialise section headers
72
+ GemAccordion.prototype.initSectionHeaders = function () {
73
+ // Loop through section headers
74
+ nodeListForEach(this.sections, function (section, i) {
75
+ // Set header attributes
76
+ var header = section.querySelector('.' + this.sectionHeaderClass)
77
+ this.initHeaderAttributes(header, i)
78
+ this.setExpanded(this.isExpanded(section), section)
79
+
80
+ // Handle events
81
+ header.addEventListener('click', this.onSectionToggle.bind(this, section))
82
+
83
+ // See if there is any state stored in sessionStorage and set the sections to
84
+ // open or closed.
85
+ this.setInitialState(section)
86
+ }.bind(this))
87
+ }
88
+
89
+ // Set individual header attributes
90
+ GemAccordion.prototype.initHeaderAttributes = function (headerWrapper, index) {
91
+ var span = headerWrapper.querySelector('.' + this.sectionButtonClass)
92
+ var heading = headerWrapper.querySelector('.' + this.sectionHeadingClass)
93
+ var summary = headerWrapper.querySelector('.' + this.sectionSummaryClass)
94
+
95
+ // Copy existing span element to an actual button element, for improved accessibility.
96
+ var button = document.createElement('button')
97
+ button.setAttribute('id', this.moduleId + '-heading-' + (index + 1))
98
+ button.setAttribute('aria-controls', this.moduleId + '-content-' + (index + 1))
99
+
100
+ // Create show / hide arrow icons with text.
101
+ var showIcons = document.createElement('span')
102
+ showIcons.classList.add(this.sectionShowHideIconClass, this.toggleLinkClass)
103
+
104
+ // Add pause after heading for assistive technology.
105
+ var srPause = document.createElement('span')
106
+ srPause.classList.add('govuk-visually-hidden')
107
+ srPause.innerHTML = ', '
108
+
109
+ // Build addtional copy for assistive technology
110
+ var srAddtionalCopy = document.createElement('span')
111
+ srAddtionalCopy.classList.add('govuk-visually-hidden')
112
+ srAddtionalCopy.innerHTML = ' this section'
113
+
114
+ // Build addtional wrapper for toggle text, place icon after wrapped text.
115
+ var wrapperShowHideIcon = document.createElement('span')
116
+ var icon = document.createElement('span')
117
+ icon.classList.add(this.upChevonIconClass)
118
+ showIcons.appendChild(icon)
119
+ wrapperShowHideIcon.classList.add(this.sectionShowHideTextClass)
120
+ showIcons.insertBefore(wrapperShowHideIcon, showIcons.childNodes[0] || null)
121
+
122
+ // Copy all attributes (https://developer.mozilla.org/en-US/docs/Web/API/Element/attributes) from span to button
123
+ for (var i = 0; i < span.attributes.length; i++) {
124
+ var attr = span.attributes.item(i)
125
+ button.setAttribute(attr.nodeName, attr.nodeValue)
126
+ }
127
+
128
+ // span could contain HTML elements (see https://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#phrasing-content)
129
+ button.innerHTML = span.innerHTML
130
+ heading.removeChild(span)
131
+ heading.appendChild(button)
132
+ button.appendChild(srPause)
133
+
134
+ // If summary content exists add to DOM in correct order
135
+ if (typeof (summary) !== 'undefined' && summary !== null) {
136
+ button.setAttribute('aria-describedby', this.moduleId + '-summary-' + (index + 1))
137
+ button.appendChild(summary)
138
+ }
139
+
140
+ button.appendChild(showIcons)
141
+ button.appendChild(srAddtionalCopy)
142
+ }
143
+
144
+ // When section toggled, set and store state
145
+ GemAccordion.prototype.onSectionToggle = function (section) {
146
+ var expanded = this.isExpanded(section)
147
+ this.setExpanded(!expanded, section)
148
+
149
+ // Store the state in sessionStorage when a change is triggered
150
+ this.storeState(section)
151
+ }
152
+
153
+ // When Open/Close All toggled, set and store state
154
+ GemAccordion.prototype.onOpenOrCloseAllToggle = function () {
155
+ var module = this
156
+ var sections = this.sections
157
+ var nowExpanded = !this.checkIfAllSectionsOpen()
158
+
159
+ nodeListForEach(sections, function (section) {
160
+ module.setExpanded(nowExpanded, section)
161
+ // Store the state in sessionStorage when a change is triggered
162
+ module.storeState(section)
163
+ })
164
+
165
+ module.updateOpenAllButton(nowExpanded)
166
+ }
167
+
168
+ // Set section attributes when opened/closed
169
+ GemAccordion.prototype.setExpanded = function (expanded, section) {
170
+ var icon = section.querySelector('.' + this.upChevonIconClass)
171
+ var showHideText = section.querySelector('.' + this.sectionShowHideTextClass)
172
+ var button = section.querySelector('.' + this.sectionButtonClass)
173
+ var newButtonText = expanded ? 'Hide' : 'Show'
174
+
175
+ showHideText.innerHTML = newButtonText
176
+ button.setAttribute('aria-expanded', expanded)
177
+ button.classList.add(this.toggleLinkClass)
178
+
179
+ // Swap icon, change class
180
+ if (expanded) {
181
+ section.classList.add(this.sectionExpandedClass)
182
+ icon.classList.remove(this.downChevonIconClass)
183
+ } else {
184
+ section.classList.remove(this.sectionExpandedClass)
185
+ icon.classList.add(this.downChevonIconClass)
186
+ }
187
+
188
+ // See if "Show all sections" button text should be updated
189
+ var areAllSectionsOpen = this.checkIfAllSectionsOpen()
190
+ this.updateOpenAllButton(areAllSectionsOpen)
191
+ }
192
+
193
+ // Get state of section
194
+ GemAccordion.prototype.isExpanded = function (section) {
195
+ return section.classList.contains(this.sectionExpandedClass)
196
+ }
197
+
198
+ // Check if all sections are open
199
+ GemAccordion.prototype.checkIfAllSectionsOpen = function () {
200
+ // Get a count of all the Accordion sections
201
+ var sectionsCount = this.sections.length
202
+ // Get a count of all Accordion sections that are expanded
203
+ var expandedSectionCount = this.$module.querySelectorAll('.' + this.sectionExpandedClass).length
204
+ var areAllSectionsOpen = sectionsCount === expandedSectionCount
205
+
206
+ return areAllSectionsOpen
207
+ }
208
+
209
+ // Update "Show all sections" button
210
+ GemAccordion.prototype.updateOpenAllButton = function (expanded) {
211
+ var icon = this.openAllButton.querySelector('.' + this.upChevonIconClass)
212
+ var openAllCopy = this.openAllButton.querySelector('.' + this.openAllTextClass)
213
+ var newButtonText = expanded ? 'Hide all sections' : 'Show all sections'
214
+ this.openAllButton.setAttribute('aria-expanded', expanded)
215
+ openAllCopy.innerHTML = newButtonText
216
+
217
+ // Swap icon, toggle class
218
+ if (expanded) {
219
+ icon.classList.remove(this.downChevonIconClass)
220
+ } else {
221
+ icon.classList.add(this.downChevonIconClass)
222
+ }
223
+ }
224
+
225
+ var helper = {
226
+ checkForSessionStorage: function () {
227
+ var testString = 'this is the test string'
228
+ var result
229
+ try {
230
+ window.sessionStorage.setItem(testString, testString)
231
+ result = window.sessionStorage.getItem(testString) === testString.toString()
232
+ window.sessionStorage.removeItem(testString)
233
+ return result
234
+ } catch (exception) {
235
+ if ((typeof console === 'undefined' || typeof console.log === 'undefined')) {
236
+ console.log('Notice: sessionStorage not available.')
237
+ }
238
+ }
239
+ }
240
+ }
241
+
242
+ // Set the state of the accordions in sessionStorage
243
+ GemAccordion.prototype.storeState = function (section) {
244
+ if (this.browserSupportsSessionStorage) {
245
+ // We need a unique way of identifying each content in the GemAccordion. Since
246
+ // an `#id` should be unique and an `id` is required for `aria-` attributes
247
+ // `id` can be safely used.
248
+ var button = section.querySelector('.' + this.sectionButtonClass)
249
+
250
+ if (button) {
251
+ var contentId = button.getAttribute('aria-controls')
252
+ var contentState = button.getAttribute('aria-expanded')
253
+
254
+ if (typeof contentId === 'undefined' && (typeof console === 'undefined' || typeof console.log === 'undefined')) {
255
+ console.error(new Error('No aria controls present in accordion section heading.'))
256
+ }
257
+
258
+ if (typeof contentState === 'undefined' && (typeof console === 'undefined' || typeof console.log === 'undefined')) {
259
+ console.error(new Error('No aria expanded present in accordion section heading.'))
260
+ }
261
+
262
+ // Only set the state when both `contentId` and `contentState` are taken from the DOM.
263
+ if (contentId && contentState) {
264
+ window.sessionStorage.setItem(contentId, contentState)
265
+ }
266
+ }
267
+ }
268
+ }
269
+
270
+ // Read the state of the accordions from sessionStorage
271
+ GemAccordion.prototype.setInitialState = function (section) {
272
+ if (this.browserSupportsSessionStorage) {
273
+ var button = section.querySelector('.' + this.sectionButtonClass)
274
+
275
+ if (button) {
276
+ var contentId = button.getAttribute('aria-controls')
277
+ var contentState = contentId ? window.sessionStorage.getItem(contentId) : null
278
+
279
+ if (contentState !== null) {
280
+ this.setExpanded(contentState === 'true', section)
281
+ }
282
+ }
283
+ }
284
+ }
285
+
286
+ Modules.GemAccordion = GemAccordion
287
+ })(window.GOVUK.Modules)
@@ -0,0 +1,8 @@
1
+ function nodeListForEach (nodes, callback) {
2
+ if (window.NodeList.prototype.forEach) {
3
+ return nodes.forEach(callback)
4
+ }
5
+ for (var i = 0; i < nodes.length; i++) {
6
+ callback.call(window, nodes[i], i, nodes);
7
+ }
8
+ }
@@ -1,25 +1,313 @@
1
- @import "govuk/components/accordion/accordion";
1
+ @import "govuk_publishing_components/component_support";
2
2
 
3
- .gem-c-accordion {
4
- .govuk-accordion__section-heading {
5
- // this is a temporary addition to fix the line height when it
6
- // is being overridden by styles from govuk-template in collections
7
- @include govuk-media-query($until: desktop) {
8
- @include govuk-font(24, $weight: bold, $line-height: 1.6);
3
+ $gem-c-accordion-border-width: 3px;
4
+ $gem-c-accordion-bottom-border-width: 1px;
5
+
6
+ // Buttons within the sections don’t need default styling
7
+ .gem-c-accordion__section-button {
8
+ display: inline-block;
9
+ margin-bottom: 0;
10
+ padding-top: govuk-spacing(3);
11
+ font-weight: bold;
12
+ @include govuk-font($size: 24, $weight: bold);
13
+ }
14
+
15
+ .gem-c-accordion__section-header {
16
+ padding-top: govuk-spacing(2) 0;
17
+ }
18
+
19
+ .gem-c-accordion__section-heading,
20
+ .gem-c-accordion__section-summary {
21
+ margin: govuk-spacing(1) 0;
22
+ }
23
+
24
+ .js-enabled {
25
+ .gem-c-accordion {
26
+ border-bottom: $gem-c-accordion-bottom-border-width solid $govuk-border-colour;
27
+ }
28
+
29
+ .gem-c-accordion__controls {
30
+ text-align: left;
31
+ }
32
+
33
+ .gem-c-accordion__open-all {
34
+ position: relative;
35
+ z-index: 1;
36
+ border-width: 0;
37
+ color: $govuk-link-colour;
38
+ background: none;
39
+ -webkit-appearance: none;
40
+ cursor: pointer;
41
+ margin-bottom: govuk-spacing(4);
42
+ padding: 0 govuk-spacing(1) govuk-spacing(1) 0;
43
+ @include govuk-font($size: 16);
44
+ @include govuk-link-common;
45
+ @include govuk-link-style-default;
46
+ // Remove default button focus outline in Firefox
47
+ &::-moz-focus-inner {
48
+ padding: 0;
49
+ border: 0;
9
50
  }
10
51
  }
11
- }
12
52
 
13
- .govuk-accordion--condensed {
14
- .govuk-accordion__section-button {
15
- @include govuk-media-query($from: tablet) {
16
- @include govuk-font($size: 19, $weight: bold);
53
+ .gem-c-accordion__open-all:hover,
54
+ .gem-c-accordion__open-all-text:hover {
55
+ text-decoration: underline;
56
+ color: $govuk-link-colour;
57
+ }
58
+
59
+ // Focus state, also to change chervon icon to black
60
+ .gem-c-accordion__open-all:focus {
61
+ .gem-c-accordion__open-all-text,
62
+ .gem-c-accordion-nav__chevron {
63
+ color: $govuk-focus-text-colour;
64
+ text-decoration: none;
17
65
  }
18
66
  }
19
67
 
20
- .govuk-accordion__section-summary {
68
+ // Create Chervon icon align with text
69
+ .gem-c-accordion-nav__chevron {
70
+ vertical-align: text-top;
71
+ display: inline-block;
72
+ box-sizing: border-box;
73
+ position: relative;
74
+ width: em(20, 14);
75
+ height: em(20, 14);
76
+ margin-left: em(5, 14);
77
+ border: em(1, 14) solid;
78
+ border-radius: em(100, 14);
79
+ // Main icon size across views, yet keep responsive for zoom
21
80
  @include govuk-media-query($from: tablet) {
22
- @include govuk-font($size: 16);
81
+ width: em(20, 16);
82
+ height: em(20, 16);
83
+ margin-left: em(5, 16);
84
+ border: em(1, 16) solid;
85
+ }
86
+
87
+ &:after {
88
+ content: "";
89
+ display: block;
90
+ box-sizing: border-box;
91
+ position: absolute;
92
+ overflow: visible;
93
+ width: em(6, 14);
94
+ height: em(6, 14);
95
+ border-top: em(2, 14) solid;
96
+ border-right: em(2, 14) solid;
97
+ transform: rotate(-45deg);
98
+ left: em(6, 14);
99
+ bottom: em(5, 14);
100
+ @include govuk-media-query($from: tablet) {
101
+ width: em(6, 16);
102
+ height: em(6, 16);
103
+ border-top: em(2, 16) solid;
104
+ border-right: em(2, 16) solid;
105
+ left: em(6, 16);
106
+ bottom: em(5, 16);
107
+ }
108
+ }
109
+ }
110
+
111
+ // Rotate icon to create "Down" version
112
+ .gem-c-accordion-nav__chevron--down {
113
+ transform: rotate(180deg);
114
+ }
115
+
116
+ .gem-c-accordion__section-heading {
117
+ // Override browser defaults to ensure consistent element height
118
+ margin-top: 0; // Override browser default
119
+ margin-bottom: 0; // Override browser default
120
+ @include govuk-font(24);
121
+ }
122
+
123
+ // Section headers have a pointer cursor as an additional affordance
124
+ .gem-c-accordion__section-header {
125
+ position: relative;
126
+ }
127
+
128
+ // For devices that can't hover such as touch devices,
129
+ // remove hover state as it can be stuck in that state (iOS).
130
+ @media (hover: none) {
131
+ .gem-c-accordion__section-header:hover {
132
+ border-top-color: $govuk-link-colour;
133
+ box-shadow: inset 0 $gem-c-accordion-border-width 0 0 $govuk-link-colour;
134
+
135
+ .gem-c-accordion__section-button {
136
+ border-top-color: $govuk-link-colour;
137
+ }
138
+ }
139
+ }
140
+
141
+ // Buttons within the headers don’t need default styling
142
+ .gem-c-accordion__section-button {
143
+ padding: govuk-spacing(2) 0 govuk-spacing(5);
144
+ position: relative;
145
+ margin: 0;
146
+ border-width: $gem-c-accordion-bottom-border-width 0 0 0;
147
+ border-top: $gem-c-accordion-bottom-border-width solid $govuk-border-colour;
148
+ color: $govuk-text-colour;
149
+ background: none;
150
+ text-align: left;
151
+ cursor: pointer;
152
+ -webkit-appearance: none;
153
+ @include govuk-typography-common;
154
+ width: 100%;
155
+
156
+ &:active {
157
+ z-index: 1;
158
+ color: $govuk-link-active-colour;
159
+ background: none;
160
+ }
161
+
162
+ // Remove default button focus outline in Firefox
163
+ &::-moz-focus-inner {
164
+ padding: 0;
165
+ border: 0;
166
+ }
167
+ }
168
+
169
+ .gem-c-accordion__section-button:hover {
170
+ color: $govuk-link-colour;
171
+ // On hover, add underline to toggle link
172
+ .gem-c-accordion__toggle-text {
173
+ text-decoration: underline;
174
+ color: $govuk-link-colour;
175
+ }
176
+ }
177
+
178
+ .gem-c-accordion__section-button:focus {
179
+ @include govuk-focused-text;
180
+ // Overwrite focus border to top
181
+ box-shadow: 0 0, 0 -4px;
182
+ border-top: 1px solid transparent;
183
+
184
+ // Focus state to change the toggle link within individual sections
185
+ .gem-c-accordion__toggle-text {
186
+ color: $govuk-focus-text-colour;
187
+ text-decoration: none;
188
+ }
189
+ // Focus state to change chervon icon colour within individual sections
190
+ .gem-c-accordion-nav__chevron {
191
+ color: $govuk-text-colour;
192
+ }
193
+ }
194
+
195
+ // Extend the touch area of the button to span the section header
196
+ .gem-c-accordion__section-button:after {
197
+ content: "";
198
+ position: absolute;
199
+ top: 0;
200
+ right: 0;
201
+ bottom: 0;
202
+ left: 0;
203
+ }
204
+
205
+ .gem-c-accordion__section-button:hover:not(:focus) {
206
+ text-decoration: none;
207
+ }
208
+
209
+ // For devices that can't hover such as touch devices,
210
+ // remove hover state as it can be stuck in that state (iOS).
211
+ @media (hover: none) {
212
+ .gem-c-accordion__section-button:hover {
213
+ text-decoration: none;
214
+ }
215
+ }
216
+
217
+ // Add toggle link with Chevron icon on right.
218
+ .gem-c-accordion__toggle-link {
219
+ display: block;
220
+ color: $govuk-link-colour;
221
+ text-transform: capitalize;
222
+ margin-top: govuk-spacing(1);
223
+ margin-bottom: govuk-spacing(1);
224
+ @include govuk-font($size: 16, $line-height: 1);
225
+
226
+ &:active {
227
+ background: $govuk-link-active-colour;
228
+ }
229
+ }
230
+
231
+ // Setting width of the text, so the icon doesn't shift (left / right) when toggled
232
+ .gem-c-accordion__toggle-text {
233
+ min-width: em(40, 16);
234
+ display: inline-block;
235
+ }
236
+
237
+ .gem-c-accordion__open-all-text {
238
+ min-width: em(120, 16);
239
+ display: inline-block;
240
+ text-align: left;
241
+ }
242
+
243
+ // Change the summary subheading size.
244
+ .gem-c-accordion__section-summary {
245
+ @include govuk-responsive-margin(2, "top");
246
+ @include govuk-responsive-margin(2, "bottom");
247
+ @include govuk-typography-common;
248
+ @include govuk-typography-responsive($size: 19);
249
+ }
250
+
251
+ // Hide body of expanded sections
252
+ .gem-c-accordion__section-content {
253
+ display: none;
254
+ @include govuk-responsive-padding(0, "top");
255
+ @include govuk-responsive-padding(8, "bottom");
256
+ }
257
+
258
+ // Show the body of expanded sections
259
+ .gem-c-accordion__section--expanded .gem-c-accordion__section-content {
260
+ display: block;
261
+ }
262
+
263
+ // Remove the bottom margin from the last item inside the content
264
+ .gem-c-accordion__section-content > :last-child {
265
+ margin-bottom: 0;
266
+ }
267
+
268
+ // Condensed layout
269
+ .gem-c-accordion--condensed {
270
+ .gem-c-accordion__open-all {
271
+ margin-bottom: govuk-spacing(5);
272
+ @include govuk-font($size: 14, $line-height: 1);
273
+ }
274
+
275
+ .gem-c-accordion__section-button {
276
+ @include govuk-typography-responsive($size: 19, $important: true);
277
+ padding-top: govuk-spacing(1);
278
+ padding-bottom: govuk-spacing(5);
279
+ }
280
+
281
+ // Reduce Chevron size
282
+ .gem-c-accordion-nav__chevron {
283
+ width: em(20, 14);
284
+ height: em(20, 14);
285
+ margin-left: em(5, 14);
286
+ border: em(1, 14) solid;
287
+ border-radius: em(100, 14);
288
+ transform: scale(.875);
289
+
290
+ &:after {
291
+ width: em(6, 14);
292
+ height: em(6, 14);
293
+ border-top: em(2, 14) solid;
294
+ border-right: em(2, 14) solid;
295
+ left: em(6, 14);
296
+ bottom: em(5, 14);
297
+ }
298
+ }
299
+
300
+ .gem-c-accordion-nav__chevron--down {
301
+ transform: scale(.875) rotate(180deg);
302
+ }
303
+
304
+ .gem-c-accordion__section-summary {
305
+ @include govuk-typography-responsive($size: 16, $important: true);
306
+ margin: govuk-spacing(1) 0;
307
+ }
308
+
309
+ .gem-c-accordion__toggle-link {
310
+ @include govuk-font($size: 14, $line-height: 1);
23
311
  }
24
312
  }
25
313
  }
@@ -5,27 +5,34 @@
5
5
  @import "../accordion";
6
6
 
7
7
  // Open all of the accordion sections.
8
- .govuk-accordion__section-content {
8
+ .gem-c-accordion__section-content {
9
9
  display: block !important; // stylelint-disable-line declaration-no-important
10
10
  }
11
11
 
12
12
  // Change the colour from the blue link colour to black.
13
- .govuk-accordion__section-button {
13
+ .gem-c-accordion__section-button {
14
14
  color: govuk-colour("black") !important; // stylelint-disable-line declaration-no-important
15
15
  }
16
16
 
17
+ // Removing spacing
18
+ .gem-c-accordion__section-header {
19
+ padding-bottom: govuk-spacing(1);
20
+ }
21
+
17
22
  // Change the summary subheading size.
18
- .govuk-accordion__section-summary {
23
+ .gem-c-accordion__section-summary {
19
24
  @include govuk-typography-common;
20
25
  @include govuk-typography-responsive($size: 16, $important: true);
26
+ }
21
27
 
22
- .govuk-accordion--condensed & {
23
- @include govuk-typography-responsive($size: 14, $important: true);
24
- }
28
+ // Hide the unusable "Show all sections" button and the "Chevron" icons.
29
+ .gem-c-accordion__open-all,
30
+ .gem-c-accordion__icon,
31
+ .gem-c-accordion__toggle-link {
32
+ display: none !important; // stylelint-disable-line declaration-no-important
25
33
  }
26
34
 
27
- // Hide the unusable "Open all" button and the "+" icons.
28
- .govuk-accordion__open-all,
29
- .govuk-accordion__icon {
35
+ // Hide all hidden content
36
+ .gem-c-accordion .govuk-visually-hidden {
30
37
  display: none !important; // stylelint-disable-line declaration-no-important
31
38
  }
@@ -39,16 +39,16 @@
39
39
  </div>
40
40
  </details>
41
41
 
42
- <div class="govuk-accordion" data-module="govuk-accordion" id="accordion-with-summary-sections">
42
+ <div class="gem-c-accordion" data-module="gem-c-accordion" id="accordion-with-summary-sections">
43
43
  <% @applications.each_with_index do |application, index| %>
44
- <div class="govuk-accordion__section ">
45
- <div class="govuk-accordion__section-header">
46
- <h2 class="govuk-accordion__section-heading">
47
- <span class="govuk-accordion__section-button" id="accordion-with-summary-sections-heading-<%= index %>">
44
+ <div class="gem-c-accordion__section ">
45
+ <div class="gem-c-accordion__section-header">
46
+ <h2 class="gem-c-accordion__section-heading">
47
+ <span class="gem-c-accordion__section-button" id="accordion-with-summary-sections-heading-<%= index %>">
48
48
  <%= application[:name] %>
49
49
  </span>
50
50
  </h2>
51
- <div class="govuk-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-<%= index %>">
51
+ <div class="gem-c-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-<%= index %>">
52
52
  <% if application[:application_found] %>
53
53
  Warnings:
54
54
  <% if application[:warning_count] > 0 %>
@@ -61,7 +61,7 @@
61
61
  <% end %>
62
62
  </div>
63
63
  </div>
64
- <div id="accordion-with-summary-sections-content-<%= index %>" class="govuk-accordion__section-content" aria-labelledby="accordion-with-summary-sections-heading-<%= index %>">
64
+ <div id="accordion-with-summary-sections-content-<%= index %>" class="gem-c-accordion__section-content" aria-labelledby="accordion-with-summary-sections-heading-<%= index %>">
65
65
  <% if application[:application_found] %>
66
66
  <% application[:warnings].each do |warning| %>
67
67
  <p class="govuk-body">
@@ -144,19 +144,19 @@
144
144
  } %>
145
145
 
146
146
  <% if @components.any? %>
147
- <div class="govuk-accordion" data-module="govuk-accordion" id="accordion-default">
148
- <div class="govuk-accordion__section ">
149
- <div class="govuk-accordion__section-header">
150
- <h2 class="govuk-accordion__section-heading">
151
- <span class="govuk-accordion__section-button" id="accordion-default-heading-1">
147
+ <div class="gem-c-accordion" data-module="gem-c-accordion" id="accordion-default">
148
+ <div class="gem-c-accordion__section ">
149
+ <div class="gem-c-accordion__section-header">
150
+ <h2 class="gem-c-accordion__section-heading">
151
+ <span class="gem-c-accordion__section-button" id="accordion-default-heading-1">
152
152
  Component files
153
153
  </span>
154
154
  </h2>
155
- <div class="govuk-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-1">
155
+ <div class="gem-c-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-1">
156
156
  Lists what files each component has
157
157
  </div>
158
158
  </div>
159
- <div id="accordion-default-content-1" class="govuk-accordion__section-content" aria-labelledby="accordion-default-heading-1">
159
+ <div id="accordion-default-content-1" class="gem-c-accordion__section-content" aria-labelledby="accordion-default-heading-1">
160
160
  <table class="govuk-table">
161
161
  <thead class="govuk-table__head">
162
162
  <tr class="govuk-table__row">
@@ -206,18 +206,18 @@
206
206
  </div>
207
207
  </div>
208
208
 
209
- <div class="govuk-accordion__section ">
210
- <div class="govuk-accordion__section-header">
211
- <h2 class="govuk-accordion__section-heading">
212
- <span class="govuk-accordion__section-button" id="accordion-default-heading-2">
209
+ <div class="gem-c-accordion__section ">
210
+ <div class="gem-c-accordion__section-header">
211
+ <h2 class="gem-c-accordion__section-heading">
212
+ <span class="gem-c-accordion__section-button" id="accordion-default-heading-2">
213
213
  Components containing components
214
214
  </span>
215
215
  </h2>
216
- <div class="govuk-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-2">
216
+ <div class="gem-c-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-2">
217
217
  Shows which components contain other components
218
218
  </div>
219
219
  </div>
220
- <div id="accordion-default-content-2" class="govuk-accordion__section-content" aria-labelledby="accordion-default-heading-2">
220
+ <div id="accordion-default-content-2" class="gem-c-accordion__section-content" aria-labelledby="accordion-default-heading-2">
221
221
  <dl class="govuk-summary-list">
222
222
  <% @components[:components_containing_components].each do |component| %>
223
223
  <div class="govuk-summary-list__row">
@@ -232,18 +232,18 @@
232
232
  </dl>
233
233
  </div>
234
234
  </div>
235
- <div class="govuk-accordion__section ">
236
- <div class="govuk-accordion__section-header">
237
- <h2 class="govuk-accordion__section-heading">
238
- <span class="govuk-accordion__section-button" id="accordion-default-heading-2">
235
+ <div class="gem-c-accordion__section ">
236
+ <div class="gem-c-accordion__section-header">
237
+ <h2 class="gem-c-accordion__section-heading">
238
+ <span class="gem-c-accordion__section-button" id="accordion-default-heading-2">
239
239
  Components by application
240
240
  </span>
241
241
  </h2>
242
- <div class="govuk-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-2">
242
+ <div class="gem-c-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-2">
243
243
  Shows which applications use each component
244
244
  </div>
245
245
  </div>
246
- <div id="accordion-default-content-2" class="govuk-accordion__section-content" aria-labelledby="accordion-default-heading-2">
246
+ <div id="accordion-default-content-2" class="gem-c-accordion__section-content" aria-labelledby="accordion-default-heading-2">
247
247
  <% if @components[:components_by_application].any? %>
248
248
  <dl class="govuk-summary-list">
249
249
  <% @components[:components_by_application].each do |component| %>
@@ -6,42 +6,35 @@
6
6
  items ||= []
7
7
  condensed ||= false
8
8
 
9
- accordion_classes = %w(gem-c-accordion govuk-accordion)
10
- accordion_classes << 'govuk-accordion--condensed' if condensed
9
+ accordion_classes = %w(gem-c-accordion)
10
+ accordion_classes << 'gem-c-accordion--condensed' if condensed
11
11
  accordion_classes << (shared_helper.get_margin_bottom)
12
12
 
13
13
  data_attributes ||= {}
14
- data_attributes[:module] = 'govuk-accordion'
14
+ data_attributes[:module] = 'gem-accordion'
15
15
  %>
16
16
  <% if items.any? %>
17
17
  <%= tag.div(class: accordion_classes, id: id, data: data_attributes) do %>
18
18
  <% items.each_with_index do |item, i| %>
19
19
  <%
20
- # Nunjucks starts a loop on 1 and the client side JavaScript also
21
- # adopts this behaviour. To prevent things from breaking, the index
22
- # here also need to be increase by one. (Nunjucks is used by GOV.UK
23
- # Frontend, which this component is based on.)
24
20
  index = i + 1
25
21
 
26
22
  item[:data_attributes] ||= nil
27
23
 
28
- section_classes = %w(govuk-accordion__section)
29
- section_classes << 'govuk-accordion__section--expanded' if item[:expanded]
24
+ section_classes = %w(gem-c-accordion__section)
25
+ section_classes << 'gem-c-accordion__section--expanded' if item[:expanded]
30
26
 
31
- summary_classes = %w(govuk-accordion__section-summary govuk-body)
27
+ summary_classes = %w(gem-c-accordion__section-summary govuk-body)
32
28
  %>
33
- <%= tag.div(class: section_classes) do %>
34
- <div class="govuk-accordion__section-header">
35
- <%=
36
- content_tag(
37
- shared_helper.get_heading_level,
38
- content_tag('span', item[:heading][:text], class: "govuk-accordion__section-button", id: "#{id}-heading-#{index}", data: item[:data_attributes]),
39
- class: 'govuk-accordion__section-heading'
40
- )
41
- %>
29
+
30
+ <%= tag.section(class: section_classes) do %>
31
+ <div class="gem-c-accordion__section-header">
32
+ <%= content_tag(shared_helper.get_heading_level, class: 'gem-c-accordion__section-heading') do %>
33
+ <%= tag.span(item[:heading][:text], id: "#{id}-heading-#{index}", data: item[:data_attributes], class: 'gem-c-accordion__section-button') %>
34
+ <% end %>
42
35
  <%= tag.div(item[:summary][:text], id: "#{id}-summary-#{index}", class: summary_classes) if item[:summary].present? %>
43
36
  </div>
44
- <%= tag.div(item[:content][:html], id: "#{id}-content-#{index}", class: "govuk-accordion__section-content", 'aria-labelledby': "#{id}-heading-#{index}") %>
37
+ <%= tag.div(item[:content][:html], id: "#{id}-content-#{index}", class: "gem-c-accordion__section-content", 'aria-label': "#{item[:heading][:text]}") %>
45
38
  <% end %>
46
39
  <% end %>
47
40
  <% end %>
@@ -6,7 +6,7 @@
6
6
  classes << "gem-c-layout-footer--border" if with_border
7
7
  %>
8
8
  <%= tag.footer class: classes, role: "contentinfo" do %>
9
- <div class="govuk-width-container" data-module="track-click">
9
+ <div class="govuk-width-container" data-module="gem-track-click">
10
10
  <% if navigation.any? %>
11
11
  <div class="govuk-footer__navigation">
12
12
  <% navigation.each do |item| %>
@@ -4,20 +4,25 @@ govuk_frontend_components:
4
4
  - accordion
5
5
  body: |
6
6
  This component is based on the [design system accordion component](https://design-system.service.gov.uk/components/accordion/)
7
- and is currently experimental. If using this component, please feed back any research findings to the Design System team.
7
+ and is currently experimental because more research is needed to validate it. If using this component, [please feed back any research findings to the Design System team](https://design-system.service.gov.uk/components/accordion/#next-steps).
8
8
 
9
9
  accessibility_criteria: |
10
10
  The accordion must:
11
11
 
12
12
  * accept focus
13
13
  * be usable with a keyboard
14
- * indicate when they have focus
14
+ * the controls must change in appearance when keyboard focus moves to it
15
+ * the controls must indicate when the mouse is hovered over it
15
16
  * be usable with touch
16
17
  * be usable with voice commands
17
18
  * have visible text
18
19
  * indicate to users that each section can be expanded and collapsed
19
20
  * inform the user when a step has been expanded or collapsed
20
- * be readable when only the text of the page is zoomed in
21
+ * be readable when only the [text of the page is zoomed in](https://support.mozilla.org/en-US/kb/font-size-and-zoom-increase-size-of-web-pages#w_how-to-only-change-the-size-of-the-text)
22
+ * zoom in up to 300% without the text spilling off the screen
23
+ * pass colour contrast
24
+ * the accordion header button element has aria-controls set to the ID of the element containing the accordion panel content.
25
+ * section content must have aria-label / aria-labelledby with a value that refers to the button that controls display of the content.
21
26
 
22
27
  Section headings must use a button element:
23
28
 
@@ -1,5 +1,5 @@
1
1
  <div class="govuk-header__logo gem-c-header__logo">
2
- <a href="/" class="govuk-header__link govuk-header__link--homepage" data-module="track-click" data-track-category="homeLinkClicked" data-track-action="homeHeader">
2
+ <a href="/" class="govuk-header__link govuk-header__link--homepage" data-module="gem-track-click" data-track-category="homeLinkClicked" data-track-action="homeHeader">
3
3
  <span class="govuk-header__logotype">
4
4
  <svg aria-hidden="true" focusable="false" class="govuk-header__logotype-crown" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 132 97" height="32" width="36">
5
5
  <path fill="currentColor" fill-rule="evenodd"
@@ -1,3 +1,3 @@
1
1
  module GovukPublishingComponents
2
- VERSION = "24.0.0".freeze
2
+ VERSION = "24.1.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_publishing_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 24.0.0
4
+ version: 24.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-09 00:00:00.000000000 Z
11
+ date: 2021-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: govuk_app_config
@@ -453,6 +453,7 @@ files:
453
453
  - app/assets/javascripts/govuk_publishing_components/vendor/json2.js
454
454
  - app/assets/javascripts/govuk_publishing_components/vendor/modernizr.js
455
455
  - app/assets/javascripts/govuk_publishing_components/vendor/polyfills/closest.js
456
+ - app/assets/javascripts/govuk_publishing_components/vendor/polyfills/common.js
456
457
  - app/assets/javascripts/govuk_publishing_components/vendor/polyfills/indexOf.js
457
458
  - app/assets/stylesheets/component_guide/application.scss
458
459
  - app/assets/stylesheets/component_guide/print.scss