govuk_publishing_components 35.15.5 → 35.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/config/govuk_publishing_components_manifest.js +1 -0
- data/app/assets/images/option-select/input-icon.svg +3 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.js +37 -15
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-video-tracker.js +7 -1
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/pii-remover.js +1 -1
- data/app/assets/javascripts/govuk_publishing_components/components/option-select.js +312 -0
- data/app/assets/stylesheets/component_guide/application.scss +6 -6
- data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +1 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_action-link.scss +15 -15
- data/app/assets/stylesheets/govuk_publishing_components/components/_big-number.scss +3 -2
- data/app/assets/stylesheets/govuk_publishing_components/components/_breadcrumbs.scss +3 -3
- data/app/assets/stylesheets/govuk_publishing_components/components/_button.scss +2 -2
- data/app/assets/stylesheets/govuk_publishing_components/components/_cards.scss +5 -5
- data/app/assets/stylesheets/govuk_publishing_components/components/_contents-list.scss +1 -1
- data/app/assets/stylesheets/govuk_publishing_components/components/_contextual-sidebar.scss +1 -1
- data/app/assets/stylesheets/govuk_publishing_components/components/_document-list.scss +2 -2
- data/app/assets/stylesheets/govuk_publishing_components/components/_image-card.scss +31 -5
- data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +40 -35
- data/app/assets/stylesheets/govuk_publishing_components/components/_option-select.scss +172 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_step-by-step-nav.scss +23 -19
- data/app/assets/stylesheets/govuk_publishing_components/components/_table.scss +6 -6
- data/app/assets/stylesheets/govuk_publishing_components/components/_tabs.scss +2 -1
- data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_steps.scss +3 -1
- data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_typography.scss +4 -4
- data/app/assets/stylesheets/govuk_publishing_components/components/mixins/_media-down.scss +2 -2
- data/app/views/govuk_publishing_components/components/_attachment.html.erb +1 -1
- data/app/views/govuk_publishing_components/components/_contents_list.html.erb +20 -10
- data/app/views/govuk_publishing_components/components/_image_card.html.erb +8 -2
- data/app/views/govuk_publishing_components/components/_option_select.html.erb +71 -0
- data/app/views/govuk_publishing_components/components/_previous_and_next_navigation.html.erb +6 -6
- data/app/views/govuk_publishing_components/components/docs/contents_list.yml +1 -0
- data/app/views/govuk_publishing_components/components/docs/image_card.yml +13 -0
- data/app/views/govuk_publishing_components/components/docs/option_select.yml +343 -0
- data/config/locales/ar.yml +5 -0
- data/config/locales/az.yml +5 -0
- data/config/locales/be.yml +5 -0
- data/config/locales/bg.yml +5 -0
- data/config/locales/bn.yml +5 -0
- data/config/locales/cs.yml +5 -0
- data/config/locales/cy.yml +5 -0
- data/config/locales/da.yml +5 -0
- data/config/locales/de.yml +5 -0
- data/config/locales/dr.yml +5 -0
- data/config/locales/el.yml +5 -0
- data/config/locales/en.yml +6 -1
- data/config/locales/es-419.yml +5 -0
- data/config/locales/es.yml +5 -0
- data/config/locales/et.yml +5 -0
- data/config/locales/fa.yml +5 -0
- data/config/locales/fi.yml +5 -0
- data/config/locales/fr.yml +5 -0
- data/config/locales/gd.yml +5 -0
- data/config/locales/gu.yml +5 -0
- data/config/locales/he.yml +5 -0
- data/config/locales/hi.yml +5 -0
- data/config/locales/hr.yml +5 -0
- data/config/locales/hu.yml +5 -0
- data/config/locales/hy.yml +5 -0
- data/config/locales/id.yml +5 -0
- data/config/locales/is.yml +5 -0
- data/config/locales/it.yml +5 -0
- data/config/locales/ja.yml +5 -0
- data/config/locales/ka.yml +5 -0
- data/config/locales/kk.yml +5 -0
- data/config/locales/ko.yml +5 -0
- data/config/locales/lt.yml +5 -0
- data/config/locales/lv.yml +5 -0
- data/config/locales/ms.yml +5 -0
- data/config/locales/mt.yml +5 -0
- data/config/locales/nl.yml +5 -0
- data/config/locales/no.yml +5 -0
- data/config/locales/pa-pk.yml +5 -0
- data/config/locales/pa.yml +5 -0
- data/config/locales/pl.yml +5 -0
- data/config/locales/ps.yml +5 -0
- data/config/locales/pt.yml +5 -0
- data/config/locales/ro.yml +5 -0
- data/config/locales/ru.yml +5 -0
- data/config/locales/si.yml +5 -0
- data/config/locales/sk.yml +5 -0
- data/config/locales/sl.yml +5 -0
- data/config/locales/so.yml +5 -0
- data/config/locales/sq.yml +5 -0
- data/config/locales/sr.yml +5 -0
- data/config/locales/sv.yml +5 -0
- data/config/locales/sw.yml +5 -0
- data/config/locales/ta.yml +5 -0
- data/config/locales/th.yml +5 -0
- data/config/locales/tk.yml +5 -0
- data/config/locales/tr.yml +5 -0
- data/config/locales/uk.yml +5 -0
- data/config/locales/ur.yml +5 -0
- data/config/locales/uz.yml +5 -0
- data/config/locales/vi.yml +5 -0
- data/config/locales/zh-hk.yml +5 -0
- data/config/locales/zh-tw.yml +5 -0
- data/config/locales/zh.yml +5 -0
- data/lib/govuk_publishing_components/presenters/contents_list_helper.rb +8 -0
- data/lib/govuk_publishing_components/presenters/image_card_helper.rb +6 -2
- data/lib/govuk_publishing_components/presenters/meta_tags.rb +3 -0
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/axe-core/axe.js +6 -6
- data/node_modules/axe-core/axe.min.js +2 -2
- data/node_modules/axe-core/locales/_template.json +4 -4
- data/node_modules/axe-core/package.json +1 -1
- data/node_modules/axe-core/sri-history.json +4 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f215a358b5348fe905ec3b11ba2d3301dd263bbe5fe6961cdab3586de5f11ead
|
4
|
+
data.tar.gz: fee32e2c6b0b5a587b36577db5f51a731b8c3df67b5d7b30db4089650edf7efd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f687a3d509cc89bd128d4c696f8f504575188b3ade7b6e536587c09be27ce7d0a3733203c52acfb48252ba6655a99b020d64d8ae5d2afbb23994e0f16a6bc2ad
|
7
|
+
data.tar.gz: 82488d3f778c9c3dc22f27eab581965780b695a43ff0585fd191771dbbf6aa05c165616c61d89873342755e9c90b13e638766f116fef25a72baf8c08a265362f
|
@@ -60,6 +60,7 @@
|
|
60
60
|
//= link govuk_publishing_components/components/_metadata.css
|
61
61
|
//= link govuk_publishing_components/components/_modal-dialogue.css
|
62
62
|
//= link govuk_publishing_components/components/_notice.css
|
63
|
+
//= link govuk_publishing_components/components/_option-select.css
|
63
64
|
//= link govuk_publishing_components/components/_organisation-logo.css
|
64
65
|
//= link govuk_publishing_components/components/_panel.css
|
65
66
|
//= link govuk_publishing_components/components/_phase-banner.css
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" width="40" height="40">
|
2
|
+
<path d="M25.7 24.8L21.9 21c.7-1 1.1-2.2 1.1-3.5 0-3.6-2.9-6.5-6.5-6.5S10 13.9 10 17.5s2.9 6.5 6.5 6.5c1.6 0 3-.6 4.1-1.5l3.7 3.7 1.4-1.4zM12 17.5c0-2.5 2-4.5 4.5-4.5s4.5 2 4.5 4.5-2 4.5-4.5 4.5-4.5-2-4.5-4.5z" fill="currentColor" />
|
3
|
+
</svg>
|
@@ -28,7 +28,7 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
|
|
28
28
|
schema_name: this.getMetaContent('schema-name'),
|
29
29
|
content_id: this.getMetaContent('content-id'),
|
30
30
|
|
31
|
-
browse_topic: this.getMetaContent('
|
31
|
+
browse_topic: this.getMetaContent('ga4-browse-topic'),
|
32
32
|
navigation_page_type: this.getMetaContent('navigation-page-type'),
|
33
33
|
navigation_list_type: this.getMetaContent('navigation-list-type'),
|
34
34
|
step_navs: this.getMetaContent('stepnavs'),
|
@@ -57,9 +57,11 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
|
|
57
57
|
emergency_banner: document.querySelector('[data-ga4-emergency-banner]') ? 'true' : undefined,
|
58
58
|
phase_banner: this.getElementAttribute('data-ga4-phase-banner') || undefined,
|
59
59
|
devolved_nations_banner: this.getElementAttribute('data-ga4-devolved-nations-banner') || undefined,
|
60
|
-
cookie_banner:
|
61
|
-
intervention: this.
|
62
|
-
query_string: this.getQueryString()
|
60
|
+
cookie_banner: this.getBannerPresence('[data-ga4-cookie-banner]'),
|
61
|
+
intervention: this.getBannerPresence('[data-ga4-intervention-banner]'),
|
62
|
+
query_string: this.getQueryString(),
|
63
|
+
search_term: this.getSearchTerm(),
|
64
|
+
spelling_suggestion: this.getMetaContent('spelling-suggestion')
|
63
65
|
}
|
64
66
|
}
|
65
67
|
window.GOVUK.analyticsGa4.core.sendData(data)
|
@@ -67,18 +69,35 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
|
|
67
69
|
},
|
68
70
|
|
69
71
|
getLocation: function () {
|
70
|
-
return this.PIIRemover.
|
72
|
+
return this.PIIRemover.stripPIIWithOverride(this.stripGaParam(document.location.href), true, true)
|
71
73
|
},
|
72
74
|
|
73
75
|
getSearch: function () {
|
74
76
|
return window.location.search
|
75
77
|
},
|
76
78
|
|
79
|
+
getSearchTerm: function () {
|
80
|
+
var queryString = this.getSearch()
|
81
|
+
|
82
|
+
if (!queryString) {
|
83
|
+
return undefined
|
84
|
+
}
|
85
|
+
|
86
|
+
var searchTerm = queryString.match(/keywords=([^&]*)/)
|
87
|
+
if (!searchTerm) {
|
88
|
+
return undefined
|
89
|
+
}
|
90
|
+
|
91
|
+
searchTerm = searchTerm[0].replace('keywords=', '')
|
92
|
+
searchTerm = this.PIIRemover.stripPIIWithOverride(searchTerm, true, true)
|
93
|
+
return searchTerm
|
94
|
+
},
|
95
|
+
|
77
96
|
getQueryString: function () {
|
78
97
|
var queryString = this.getSearch()
|
79
98
|
if (queryString) {
|
80
|
-
queryString = this.PIIRemover.stripPIIWithOverride(queryString, true, true)
|
81
99
|
queryString = this.stripGaParam(queryString)
|
100
|
+
queryString = this.PIIRemover.stripPIIWithOverride(queryString, true, true)
|
82
101
|
queryString = queryString.substring(1) // removes the '?' character from the start.
|
83
102
|
return queryString
|
84
103
|
}
|
@@ -97,7 +116,7 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
|
|
97
116
|
},
|
98
117
|
|
99
118
|
getTitle: function () {
|
100
|
-
return this.PIIRemover.
|
119
|
+
return this.PIIRemover.stripPIIWithOverride(document.title, true, true)
|
101
120
|
},
|
102
121
|
|
103
122
|
// window.httpStatusCode is set in the source of the error page in static
|
@@ -130,7 +149,10 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
|
|
130
149
|
var content = document.getElementById('content')
|
131
150
|
var html = document.querySelector('html')
|
132
151
|
if (content) {
|
133
|
-
|
152
|
+
var contentLanguage = content.getAttribute('lang')
|
153
|
+
if (contentLanguage) {
|
154
|
+
return contentLanguage
|
155
|
+
}
|
134
156
|
}
|
135
157
|
// html.getAttribute('lang') is untested - Jasmine would not allow lang to be set on <html>.
|
136
158
|
return html.getAttribute('lang') || this.nullValue
|
@@ -146,18 +168,18 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
|
|
146
168
|
return (withdrawn === 'withdrawn') ? 'true' : 'false'
|
147
169
|
},
|
148
170
|
|
149
|
-
|
171
|
+
getBannerPresence: function (bannerSelector) {
|
150
172
|
/* If the user hides the banner using JS, a cookie is set to hide it on future page loads.
|
151
|
-
* Therefore we need to start the
|
173
|
+
* Therefore we need to start the banner module early so that it hides if this cookie exists.
|
152
174
|
* Without this, our pageview object will track the banner as visible before it gets hidden. */
|
153
175
|
|
154
|
-
var
|
176
|
+
var banner = document.querySelector(bannerSelector)
|
155
177
|
|
156
|
-
if (
|
157
|
-
window.GOVUK.modules.start(
|
158
|
-
var
|
178
|
+
if (banner) {
|
179
|
+
window.GOVUK.modules.start(banner)
|
180
|
+
var bannerHidden = banner.getAttribute('hidden') === '' || banner.getAttribute('hidden')
|
159
181
|
|
160
|
-
if (
|
182
|
+
if (bannerHidden) {
|
161
183
|
return undefined
|
162
184
|
}
|
163
185
|
return 'true'
|
@@ -70,7 +70,7 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
|
|
70
70
|
var data = {}
|
71
71
|
data.event_name = 'video_' + event
|
72
72
|
data.type = 'video'
|
73
|
-
data.url = player.getVideoUrl()
|
73
|
+
data.url = this.cleanVideoUrl(player.getVideoUrl())
|
74
74
|
data.text = player.videoTitle
|
75
75
|
data.action = event
|
76
76
|
data.video_current_time = Math.round(player.getCurrentTime())
|
@@ -81,6 +81,12 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
|
|
81
81
|
var schema = schemas.mergeProperties(data, 'event_data')
|
82
82
|
|
83
83
|
window.GOVUK.analyticsGa4.core.sendData(schema)
|
84
|
+
},
|
85
|
+
|
86
|
+
cleanVideoUrl: function (url) {
|
87
|
+
url = url.replace(/[?]{1}t=[0-9]+[&]{1}/, '?') // replace ?t=123& with ?
|
88
|
+
url = url.replace(/[&]{1}t=[0-9]+/, '') // replace &t=123 with ''
|
89
|
+
return url
|
84
90
|
}
|
85
91
|
}
|
86
92
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
'use strict'
|
3
3
|
|
4
4
|
var GOVUK = global.GOVUK || {}
|
5
|
-
var EMAIL_PATTERN = /[^\s
|
5
|
+
var EMAIL_PATTERN = /[^\s=/?&#+]+(?:@|%40)[^\s=/?&+]+/g
|
6
6
|
var POSTCODE_PATTERN = /\b[A-PR-UWYZ][A-HJ-Z]?[0-9][0-9A-HJKMNPR-Y]?(?:[\s+]|%20)*[0-9](?!refund)[ABD-HJLNPQ-Z]{2,3}\b/gi
|
7
7
|
var DATE_PATTERN_NUMERIC = /\d{4}(-?)\d{2}(-?)\d{2}/g
|
8
8
|
var DATE_PATTERN_STRING = /\d{1,2}\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}/g
|
@@ -0,0 +1,312 @@
|
|
1
|
+
window.GOVUK = window.GOVUK || {}
|
2
|
+
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
3
|
+
|
4
|
+
(function (Modules) {
|
5
|
+
/* This JavaScript provides two functional enhancements to option-select components:
|
6
|
+
1) A count that shows how many results have been checked in the option-container
|
7
|
+
2) Open/closing of the list of checkboxes
|
8
|
+
*/
|
9
|
+
function OptionSelect ($module) {
|
10
|
+
this.$optionSelect = $module
|
11
|
+
this.$options = this.$optionSelect.querySelectorAll("input[type='checkbox']")
|
12
|
+
this.$optionsContainer = this.$optionSelect.querySelector('.js-options-container')
|
13
|
+
this.$optionList = this.$optionsContainer.querySelector('.js-auto-height-inner')
|
14
|
+
this.$allCheckboxes = this.$optionsContainer.querySelectorAll('.govuk-checkboxes__item')
|
15
|
+
this.hasFilter = this.$optionSelect.getAttribute('data-filter-element') || ''
|
16
|
+
|
17
|
+
this.checkedCheckboxes = []
|
18
|
+
|
19
|
+
this.mq = window.matchMedia('(min-width: 641px)')
|
20
|
+
this.isClosedOnLoad = this.$optionSelect.getAttribute('data-closed-on-load')
|
21
|
+
this.isClosedOnLoadMobile = this.$optionSelect.getAttribute('data-closed-on-load-mobile')
|
22
|
+
}
|
23
|
+
|
24
|
+
OptionSelect.prototype.init = function () {
|
25
|
+
if (this.hasFilter.length) {
|
26
|
+
var filterEl = document.createElement('div')
|
27
|
+
filterEl.innerHTML = this.hasFilter
|
28
|
+
|
29
|
+
var optionSelectFilter = document.createElement('div')
|
30
|
+
optionSelectFilter.classList.add('gem-c-option-select__filter')
|
31
|
+
optionSelectFilter.innerHTML = filterEl.childNodes[0].nodeValue
|
32
|
+
|
33
|
+
this.$optionsContainer.parentNode.insertBefore(optionSelectFilter, this.$optionsContainer)
|
34
|
+
|
35
|
+
this.$filter = this.$optionSelect.querySelector('input[name="option-select-filter"]')
|
36
|
+
this.$filterCount = document.getElementById(this.$filter.getAttribute('aria-describedby'))
|
37
|
+
this.filterTextSingle = ' ' + this.$filterCount.getAttribute('data-single')
|
38
|
+
this.filterTextMultiple = ' ' + this.$filterCount.getAttribute('data-multiple')
|
39
|
+
this.filterTextSelected = ' ' + this.$filterCount.getAttribute('data-selected')
|
40
|
+
this.checkboxLabels = []
|
41
|
+
this.filterTimeout = 0
|
42
|
+
|
43
|
+
this.getAllCheckedCheckboxes()
|
44
|
+
for (var i = 0; i < this.$allCheckboxes.length; i++) {
|
45
|
+
this.checkboxLabels.push(this.cleanString(this.$allCheckboxes[i].textContent))
|
46
|
+
}
|
47
|
+
|
48
|
+
this.$filter.addEventListener('keyup', this.typeFilterText.bind(this))
|
49
|
+
}
|
50
|
+
|
51
|
+
// Attach listener to update checked count
|
52
|
+
this.$optionsContainer.querySelector('.gem-c-checkboxes__list').addEventListener('change', this.updateCheckedCount.bind(this))
|
53
|
+
|
54
|
+
// Replace div.container-head with a button
|
55
|
+
this.replaceHeadingSpanWithButton()
|
56
|
+
|
57
|
+
// Add js-collapsible class to parent for CSS
|
58
|
+
this.$optionSelect.classList.add('js-collapsible')
|
59
|
+
|
60
|
+
// Add open/close listeners
|
61
|
+
var button = this.$optionSelect.querySelector('.js-container-button')
|
62
|
+
button.addEventListener('click', this.toggleOptionSelect.bind(this))
|
63
|
+
|
64
|
+
// Toggle option visibility depending on screen size (min-width: 641px) and
|
65
|
+
// presence of any 'closed' properties (`data-closed-on-load`, `data-closed-on-load-mobile`).
|
66
|
+
// See https://github.com/alphagov/govuk-frontend/blob/main/packages/govuk-frontend/src/govuk/settings/_media-queries.scss#L10-L14
|
67
|
+
if (this.mq.matches) {
|
68
|
+
this.toggleVisibility(true)
|
69
|
+
} else {
|
70
|
+
this.toggleVisibility(false)
|
71
|
+
}
|
72
|
+
|
73
|
+
var checkedString = this.checkedString()
|
74
|
+
if (checkedString) {
|
75
|
+
this.attachCheckedCounter(checkedString)
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
OptionSelect.prototype.toggleVisibility = function (isTabletOrLarger) {
|
80
|
+
if (isTabletOrLarger) {
|
81
|
+
if (this.isClosedOnLoad === 'true') {
|
82
|
+
this.close()
|
83
|
+
} else {
|
84
|
+
this.setupHeight()
|
85
|
+
}
|
86
|
+
} else {
|
87
|
+
if (this.isClosedOnLoadMobile === 'true' || this.isClosedOnLoad === 'true') {
|
88
|
+
this.close()
|
89
|
+
} else {
|
90
|
+
this.setContainerHeight(201)
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
OptionSelect.prototype.typeFilterText = function (event) {
|
96
|
+
event.stopPropagation()
|
97
|
+
var ENTER_KEY = 13
|
98
|
+
|
99
|
+
if (event.keyCode !== ENTER_KEY) {
|
100
|
+
clearTimeout(this.filterTimeout)
|
101
|
+
this.filterTimeout = setTimeout(
|
102
|
+
function () { this.doFilter(this) }.bind(this),
|
103
|
+
300
|
104
|
+
)
|
105
|
+
} else {
|
106
|
+
event.preventDefault() // prevents finder forms from being submitted when user presses ENTER
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
OptionSelect.prototype.cleanString = function cleanString (text) {
|
111
|
+
text = text.replace(/&/g, 'and')
|
112
|
+
text = text.replace(/[’',:–-]/g, '') // remove punctuation characters
|
113
|
+
text = text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // escape special characters
|
114
|
+
return text.trim().replace(/\s\s+/g, ' ').toLowerCase() // replace multiple spaces with one
|
115
|
+
}
|
116
|
+
|
117
|
+
OptionSelect.prototype.getAllCheckedCheckboxes = function getAllCheckedCheckboxes () {
|
118
|
+
this.checkedCheckboxes = []
|
119
|
+
|
120
|
+
for (var i = 0; i < this.$options.length; i++) {
|
121
|
+
if (this.$options[i].checked) {
|
122
|
+
this.checkedCheckboxes.push(i)
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
OptionSelect.prototype.doFilter = function doFilter (obj) {
|
128
|
+
var filterBy = obj.cleanString(obj.$filter.value)
|
129
|
+
var showCheckboxes = obj.checkedCheckboxes.slice()
|
130
|
+
var i = 0
|
131
|
+
|
132
|
+
for (i = 0; i < obj.$allCheckboxes.length; i++) {
|
133
|
+
if (showCheckboxes.indexOf(i) === -1 && obj.checkboxLabels[i].search(filterBy) !== -1) {
|
134
|
+
showCheckboxes.push(i)
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
for (i = 0; i < obj.$allCheckboxes.length; i++) {
|
139
|
+
obj.$allCheckboxes[i].style.display = 'none'
|
140
|
+
}
|
141
|
+
|
142
|
+
for (i = 0; i < showCheckboxes.length; i++) {
|
143
|
+
obj.$allCheckboxes[showCheckboxes[i]].style.display = 'block'
|
144
|
+
}
|
145
|
+
|
146
|
+
var lenChecked = obj.$optionsContainer.querySelectorAll('.govuk-checkboxes__input:checked').length
|
147
|
+
var len = showCheckboxes.length + lenChecked
|
148
|
+
var html = len + (len === 1 ? obj.filterTextSingle : obj.filterTextMultiple) + ', ' + lenChecked + obj.filterTextSelected
|
149
|
+
obj.$filterCount.innerHTML = html
|
150
|
+
}
|
151
|
+
|
152
|
+
OptionSelect.prototype.replaceHeadingSpanWithButton = function replaceHeadingSpanWithButton () {
|
153
|
+
/* Replace the span within the heading with a button element. This is based on feedback from Léonie Watson.
|
154
|
+
* The button has all of the accessibility hooks that are used by screen readers and etc.
|
155
|
+
* We do this in the JavaScript because if the JavaScript is not active then the button shouldn't
|
156
|
+
* be there as there is no JS to handle the click event.
|
157
|
+
*/
|
158
|
+
var containerHead = this.$optionSelect.querySelector('.js-container-button')
|
159
|
+
var jsContainerHeadHTML = containerHead.innerHTML
|
160
|
+
|
161
|
+
// Create button and replace the preexisting html with the button.
|
162
|
+
var button = document.createElement('button')
|
163
|
+
button.setAttribute('class', 'js-container-button gem-c-option-select__title gem-c-option-select__button')
|
164
|
+
// Add type button to override default type submit when this component is used within a form
|
165
|
+
button.setAttribute('type', 'button')
|
166
|
+
button.setAttribute('aria-expanded', true)
|
167
|
+
button.setAttribute('id', containerHead.getAttribute('id'))
|
168
|
+
button.setAttribute('aria-controls', this.$optionsContainer.getAttribute('id'))
|
169
|
+
button.innerHTML = jsContainerHeadHTML
|
170
|
+
containerHead.parentNode.replaceChild(button, containerHead)
|
171
|
+
|
172
|
+
// GA4 Accordion tracking. Relies on the ga4-finder-tracker setting the index first, so we wrap this in a custom event.
|
173
|
+
window.addEventListener('ga4-filter-indexes-added', function () {
|
174
|
+
if (window.GOVUK.analyticsGa4) {
|
175
|
+
if (window.GOVUK.analyticsGa4.Ga4FinderTracker) {
|
176
|
+
window.GOVUK.analyticsGa4.Ga4FinderTracker.addFilterButtonTracking(button, button.innerHTML)
|
177
|
+
}
|
178
|
+
}
|
179
|
+
})
|
180
|
+
}
|
181
|
+
|
182
|
+
OptionSelect.prototype.attachCheckedCounter = function attachCheckedCounter (checkedString) {
|
183
|
+
var element = document.createElement('div')
|
184
|
+
element.setAttribute('class', 'gem-c-option-select__selected-counter js-selected-counter')
|
185
|
+
element.innerHTML = checkedString
|
186
|
+
this.$optionSelect.querySelector('.js-container-button').insertAdjacentElement('afterend', element)
|
187
|
+
}
|
188
|
+
|
189
|
+
OptionSelect.prototype.updateCheckedCount = function updateCheckedCount () {
|
190
|
+
var checkedString = this.checkedString()
|
191
|
+
var checkedStringElement = this.$optionSelect.querySelector('.js-selected-counter')
|
192
|
+
|
193
|
+
if (checkedString) {
|
194
|
+
if (checkedStringElement === null) {
|
195
|
+
this.attachCheckedCounter(checkedString)
|
196
|
+
} else {
|
197
|
+
checkedStringElement.textContent = checkedString
|
198
|
+
}
|
199
|
+
} else if (checkedStringElement) {
|
200
|
+
checkedStringElement.parentNode.removeChild(checkedStringElement)
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
OptionSelect.prototype.checkedString = function checkedString () {
|
205
|
+
this.getAllCheckedCheckboxes()
|
206
|
+
var count = this.checkedCheckboxes.length
|
207
|
+
var checkedString = false
|
208
|
+
if (count > 0) {
|
209
|
+
checkedString = count + ' selected'
|
210
|
+
}
|
211
|
+
|
212
|
+
return checkedString
|
213
|
+
}
|
214
|
+
|
215
|
+
OptionSelect.prototype.toggleOptionSelect = function toggleOptionSelect (e) {
|
216
|
+
if (this.isClosed()) {
|
217
|
+
this.open()
|
218
|
+
} else {
|
219
|
+
this.close()
|
220
|
+
}
|
221
|
+
e.preventDefault()
|
222
|
+
}
|
223
|
+
|
224
|
+
OptionSelect.prototype.open = function open () {
|
225
|
+
if (this.isClosed()) {
|
226
|
+
this.$optionSelect.querySelector('.js-container-button').setAttribute('aria-expanded', true)
|
227
|
+
this.$optionSelect.classList.remove('js-closed')
|
228
|
+
this.$optionSelect.classList.add('js-opened')
|
229
|
+
if (!this.$optionsContainer.style.height) {
|
230
|
+
this.setupHeight()
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
OptionSelect.prototype.close = function close () {
|
236
|
+
this.$optionSelect.classList.remove('js-opened')
|
237
|
+
this.$optionSelect.classList.add('js-closed')
|
238
|
+
this.$optionSelect.querySelector('.js-container-button').setAttribute('aria-expanded', false)
|
239
|
+
}
|
240
|
+
|
241
|
+
OptionSelect.prototype.isClosed = function isClosed () {
|
242
|
+
return this.$optionSelect.classList.contains('js-closed')
|
243
|
+
}
|
244
|
+
|
245
|
+
OptionSelect.prototype.setContainerHeight = function setContainerHeight (height) {
|
246
|
+
this.$optionsContainer.style.height = height + 'px'
|
247
|
+
}
|
248
|
+
|
249
|
+
OptionSelect.prototype.isCheckboxVisible = function isCheckboxVisible (option) {
|
250
|
+
var initialOptionContainerHeight = this.$optionsContainer.clientHeight
|
251
|
+
var optionListOffsetTop = this.$optionList.getBoundingClientRect().top
|
252
|
+
var distanceFromTopOfContainer = option.getBoundingClientRect().top - optionListOffsetTop
|
253
|
+
return distanceFromTopOfContainer < initialOptionContainerHeight
|
254
|
+
}
|
255
|
+
|
256
|
+
OptionSelect.prototype.getVisibleCheckboxes = function getVisibleCheckboxes () {
|
257
|
+
var visibleCheckboxes = []
|
258
|
+
for (var i = 0; i < this.$options.length; i++) {
|
259
|
+
if (this.isCheckboxVisible(this.$options[i])) {
|
260
|
+
visibleCheckboxes.push(this.$options[i])
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
// add an extra checkbox, if the label of the first is too long it collapses onto itself
|
265
|
+
if (this.$options[visibleCheckboxes.length]) {
|
266
|
+
visibleCheckboxes.push(this.$options[visibleCheckboxes.length])
|
267
|
+
}
|
268
|
+
return visibleCheckboxes
|
269
|
+
}
|
270
|
+
|
271
|
+
OptionSelect.prototype.isComponentParentHidden = function isComponentParentHidden () {
|
272
|
+
var parentContent = this.$optionSelect.parentElement
|
273
|
+
var isparentContentHidden = false
|
274
|
+
// check whether this is hidden by progressive disclosure,
|
275
|
+
// because height calculations won't work
|
276
|
+
// would use offsetParent === null but for IE10+
|
277
|
+
if (parentContent) {
|
278
|
+
isparentContentHidden = !(parentContent.offsetWidth || parentContent.offsetHeight || parentContent.getClientRects().length)
|
279
|
+
}
|
280
|
+
|
281
|
+
return isparentContentHidden
|
282
|
+
}
|
283
|
+
|
284
|
+
OptionSelect.prototype.setupHeight = function setupHeight () {
|
285
|
+
var initialOptionContainerHeight = this.$optionsContainer.clientHeight
|
286
|
+
var height = this.$optionList.offsetHeight
|
287
|
+
|
288
|
+
var isComponentParentHidden = this.isComponentParentHidden()
|
289
|
+
|
290
|
+
if (isComponentParentHidden) {
|
291
|
+
initialOptionContainerHeight = 200
|
292
|
+
height = 200
|
293
|
+
}
|
294
|
+
|
295
|
+
// Resize if the list is only slightly bigger than its container
|
296
|
+
// If isComponentParentHidden is true, then 200 < 250
|
297
|
+
// And the container height is always set to 201px
|
298
|
+
if (height < initialOptionContainerHeight + 50) {
|
299
|
+
this.setContainerHeight(height + 1)
|
300
|
+
return
|
301
|
+
}
|
302
|
+
|
303
|
+
// Resize to cut last item cleanly in half
|
304
|
+
var visibleCheckboxes = this.getVisibleCheckboxes()
|
305
|
+
|
306
|
+
var lastVisibleCheckbox = visibleCheckboxes[visibleCheckboxes.length - 1]
|
307
|
+
var position = lastVisibleCheckbox.parentNode.offsetTop // parent element is relative
|
308
|
+
this.setContainerHeight(position + (lastVisibleCheckbox.clientHeight / 1.5))
|
309
|
+
}
|
310
|
+
|
311
|
+
Modules.OptionSelect = OptionSelect
|
312
|
+
})(window.GOVUK.Modules)
|
@@ -145,7 +145,7 @@ $gem-guide-border-width: 1px;
|
|
145
145
|
border: 0;
|
146
146
|
padding: govuk-spacing(2);
|
147
147
|
|
148
|
-
|
148
|
+
&::before {
|
149
149
|
display: none;
|
150
150
|
}
|
151
151
|
}
|
@@ -187,7 +187,7 @@ $gem-guide-border-width: 1px;
|
|
187
187
|
font-style: italic;
|
188
188
|
}
|
189
189
|
|
190
|
-
|
190
|
+
&::before {
|
191
191
|
@include govuk-font($size: 14);
|
192
192
|
content: attr(data-content);
|
193
193
|
position: absolute;
|
@@ -201,7 +201,7 @@ $gem-guide-border-width: 1px;
|
|
201
201
|
.component-guide-preview--warning {
|
202
202
|
border-color: govuk-colour("yellow");
|
203
203
|
|
204
|
-
|
204
|
+
&::before {
|
205
205
|
background-color: govuk-colour("yellow");
|
206
206
|
}
|
207
207
|
}
|
@@ -209,7 +209,7 @@ $gem-guide-border-width: 1px;
|
|
209
209
|
.component-guide-preview--violation {
|
210
210
|
border-color: govuk-colour("red");
|
211
211
|
|
212
|
-
|
212
|
+
&::before {
|
213
213
|
background-color: govuk-colour("red");
|
214
214
|
color: govuk-colour("white");
|
215
215
|
}
|
@@ -516,11 +516,11 @@ $code-delete-bg: #fadddd;
|
|
516
516
|
}
|
517
517
|
|
518
518
|
.component__count {
|
519
|
-
|
519
|
+
&::before {
|
520
520
|
content: "(";
|
521
521
|
}
|
522
522
|
|
523
|
-
|
523
|
+
&::after {
|
524
524
|
content: ")";
|
525
525
|
}
|
526
526
|
}
|
@@ -57,6 +57,7 @@ $govuk-new-link-styles: true;
|
|
57
57
|
@import "components/metadata";
|
58
58
|
@import "components/modal-dialogue";
|
59
59
|
@import "components/notice";
|
60
|
+
@import "components/option-select";
|
60
61
|
@import "components/organisation-logo";
|
61
62
|
@import "components/panel";
|
62
63
|
@import "components/phase-banner";
|
@@ -3,7 +3,7 @@
|
|
3
3
|
.gem-c-action-link {
|
4
4
|
display: table;
|
5
5
|
|
6
|
-
|
6
|
+
&::before {
|
7
7
|
content: "";
|
8
8
|
display: table-cell;
|
9
9
|
width: 60px;
|
@@ -66,7 +66,7 @@
|
|
66
66
|
.gem-c-action-link__subtext {
|
67
67
|
padding: 0;
|
68
68
|
|
69
|
-
|
69
|
+
&::before {
|
70
70
|
display: none;
|
71
71
|
}
|
72
72
|
}
|
@@ -82,7 +82,7 @@
|
|
82
82
|
position: relative;
|
83
83
|
padding-left: govuk-spacing(4);
|
84
84
|
|
85
|
-
|
85
|
+
&::before {
|
86
86
|
content: "";
|
87
87
|
position: absolute;
|
88
88
|
top: 10%;
|
@@ -95,14 +95,14 @@
|
|
95
95
|
}
|
96
96
|
|
97
97
|
.gem-c-action-link--white-arrow {
|
98
|
-
|
98
|
+
&::before {
|
99
99
|
background-image: image-url("govuk_publishing_components/action-link-arrow--white.png");
|
100
100
|
background-image: image-url("govuk_publishing_components/action-link-arrow--white.svg"), linear-gradient(transparent, transparent);
|
101
101
|
}
|
102
102
|
}
|
103
103
|
|
104
104
|
.gem-c-action-link--blue-arrow {
|
105
|
-
|
105
|
+
&::before {
|
106
106
|
width: 36px;
|
107
107
|
height: 28px;
|
108
108
|
background: image-url("govuk_publishing_components/action-link-arrow--blue.png");
|
@@ -120,7 +120,7 @@
|
|
120
120
|
}
|
121
121
|
|
122
122
|
.gem-c-action-link--simple {
|
123
|
-
|
123
|
+
&::before {
|
124
124
|
width: 30px;
|
125
125
|
height: 30px;
|
126
126
|
background: image-url("govuk_publishing_components/action-link-arrow--simple.png");
|
@@ -132,7 +132,7 @@
|
|
132
132
|
}
|
133
133
|
|
134
134
|
.gem-c-action-link--simple-light {
|
135
|
-
|
135
|
+
&::before {
|
136
136
|
width: 30px;
|
137
137
|
height: 30px;
|
138
138
|
background: image-url("govuk_publishing_components/action-link-arrow--simple-light.png");
|
@@ -144,14 +144,14 @@
|
|
144
144
|
}
|
145
145
|
|
146
146
|
.gem-c-action-link--dark-icon {
|
147
|
-
|
147
|
+
&::before {
|
148
148
|
background: image-url("govuk_publishing_components/action-link-arrow--dark.png");
|
149
149
|
background: image-url("govuk_publishing_components/action-link-arrow--dark.svg"), linear-gradient(transparent, transparent);
|
150
150
|
}
|
151
151
|
}
|
152
152
|
|
153
153
|
.gem-c-action-link--dark-large-icon {
|
154
|
-
|
154
|
+
&::before {
|
155
155
|
background: image-url("govuk_publishing_components/action-link-arrow--dark.png");
|
156
156
|
background: image-url("govuk_publishing_components/action-link-arrow--dark.svg"), linear-gradient(transparent, transparent);
|
157
157
|
height: 34px;
|
@@ -174,7 +174,7 @@
|
|
174
174
|
margin-bottom: govuk-spacing(2);
|
175
175
|
}
|
176
176
|
|
177
|
-
|
177
|
+
&::before {
|
178
178
|
height: 30px;
|
179
179
|
width: 35px;
|
180
180
|
background-repeat: no-repeat;
|
@@ -184,7 +184,7 @@
|
|
184
184
|
}
|
185
185
|
|
186
186
|
.gem-c-action-link--transparent-icon {
|
187
|
-
|
187
|
+
&::before {
|
188
188
|
background-image: image-url("govuk_publishing_components/action-link-arrow--transparent.svg");
|
189
189
|
}
|
190
190
|
}
|
@@ -192,7 +192,7 @@
|
|
192
192
|
.gem-c-action-link--brexit {
|
193
193
|
max-width: none;
|
194
194
|
|
195
|
-
|
195
|
+
&::before {
|
196
196
|
height: 30px;
|
197
197
|
width: 30px;
|
198
198
|
background-image: image-url("govuk_publishing_components/action-link-arrow--brexit.svg");
|
@@ -208,7 +208,7 @@
|
|
208
208
|
@include govuk-media-query($from: tablet) {
|
209
209
|
margin-bottom: govuk-spacing(2);
|
210
210
|
|
211
|
-
|
211
|
+
&::before {
|
212
212
|
width: 35px;
|
213
213
|
background-position: 0 4px;
|
214
214
|
background-size: 25px auto;
|
@@ -217,7 +217,7 @@
|
|
217
217
|
}
|
218
218
|
|
219
219
|
.gem-c-action-link--nhs {
|
220
|
-
|
220
|
+
&::before {
|
221
221
|
width: 80px;
|
222
222
|
height: 70px;
|
223
223
|
background: image-url("govuk_publishing_components/action-link--nhs.png");
|
@@ -232,7 +232,7 @@
|
|
232
232
|
color: govuk-colour("white");
|
233
233
|
|
234
234
|
.gem-c-action-link__subtext {
|
235
|
-
|
235
|
+
&::before {
|
236
236
|
border-color: govuk-colour("white");
|
237
237
|
}
|
238
238
|
}
|
@@ -16,8 +16,9 @@
|
|
16
16
|
@include govuk-font($size: 19, $weight: bold);
|
17
17
|
|
18
18
|
// This pseudo element is to bypass an issue with NVDA where block level elements are dictated separately.
|
19
|
-
// What's happening here is that the label and the number technically have an inline relationship
|
20
|
-
|
19
|
+
// What's happening here is that the label and the number technically have an inline relationship
|
20
|
+
// but appear to have a block relationship thanks to this element
|
21
|
+
&::before {
|
21
22
|
content: "";
|
22
23
|
display: block;
|
23
24
|
}
|