govuk_publishing_components 24.0.0 → 24.1.0

Sign up to get free protection for your applications and to get access to all the features.
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