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 +4 -4
- data/app/assets/javascripts/govuk_publishing_components/components/accordion.js +286 -4
- data/app/assets/javascripts/govuk_publishing_components/vendor/polyfills/common.js +8 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_accordion.scss +302 -14
- data/app/assets/stylesheets/govuk_publishing_components/components/print/_accordion.scss +16 -9
- data/app/views/govuk_publishing_components/audit/show.html.erb +26 -26
- data/app/views/govuk_publishing_components/components/_accordion.html.erb +13 -20
- data/app/views/govuk_publishing_components/components/_layout_footer.html.erb +1 -1
- data/app/views/govuk_publishing_components/components/docs/accordion.yml +8 -3
- data/app/views/govuk_publishing_components/components/layout_header/_header_logo.html.erb +1 -1
- data/lib/govuk_publishing_components/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93a8bde02a39806e02cc9007a6b503aa3e65af3f1e7768b29f1d82c2c0ae66c4
|
4
|
+
data.tar.gz: b1e3bf6f8b98f5a4dcf2847fdca19aeed81b140491d43c230a5ea7074961d91b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64cffb98c5dc002910a32ee736f21500ca921d5c3e5d165f66f87688d4e2a589da8e4aa69deba06b953924cf152aaac39e2f19752e80f7d7184285c9ce43bf8e
|
7
|
+
data.tar.gz: d1defc316e8d5e7171d903fa874ef1d8c93d416f1ce28e4c860aaed644b088e9621e24b2fb5a955768234a0d8d642193283509819348693b39c121e584aeeb5f
|
@@ -1,5 +1,287 @@
|
|
1
|
-
|
2
|
-
//
|
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
|
-
|
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)
|
@@ -1,25 +1,313 @@
|
|
1
|
-
@import "
|
1
|
+
@import "govuk_publishing_components/component_support";
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
.
|
14
|
-
.
|
15
|
-
|
16
|
-
|
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
|
-
|
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
|
-
|
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
|
-
.
|
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
|
-
.
|
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
|
-
.
|
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
|
-
|
23
|
-
|
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
|
28
|
-
.govuk-
|
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="
|
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="
|
45
|
-
<div class="
|
46
|
-
<h2 class="
|
47
|
-
<span class="
|
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="
|
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="
|
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="
|
148
|
-
<div class="
|
149
|
-
<div class="
|
150
|
-
<h2 class="
|
151
|
-
<span class="
|
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="
|
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="
|
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="
|
210
|
-
<div class="
|
211
|
-
<h2 class="
|
212
|
-
<span class="
|
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="
|
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="
|
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="
|
236
|
-
<div class="
|
237
|
-
<h2 class="
|
238
|
-
<span class="
|
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="
|
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="
|
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
|
10
|
-
accordion_classes << '
|
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] = '
|
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(
|
29
|
-
section_classes << '
|
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(
|
27
|
+
summary_classes = %w(gem-c-accordion__section-summary govuk-body)
|
32
28
|
%>
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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: "
|
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.
|
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
|
-
*
|
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"
|
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.
|
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-
|
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
|