govuk_publishing_components 30.2.0 → 30.4.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/analytics/page-content.js +8 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-event-tracker.js +6 -6
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js +23 -5
- data/app/assets/javascripts/govuk_publishing_components/components/checkboxes.js +0 -22
- data/app/assets/stylesheets/component_guide/application.scss +4 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_layout-footer.scss +7 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +1 -1
- data/app/models/govuk_publishing_components/component_example.rb +3 -2
- data/app/views/govuk_publishing_components/component_guide/show.html.erb +26 -2
- data/app/views/govuk_publishing_components/components/_checkboxes.html.erb +2 -3
- data/app/views/govuk_publishing_components/components/docs/textarea.yml +7 -0
- data/config/locales/en.yml +4 -0
- data/lib/govuk_publishing_components/presenters/checkboxes_helper.rb +2 -4
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/sortablejs/README.md +828 -815
- data/node_modules/sortablejs/Sortable.js +186 -113
- data/node_modules/sortablejs/Sortable.min.js +2 -2
- data/node_modules/sortablejs/modular/sortable.complete.esm.js +184 -111
- data/node_modules/sortablejs/modular/sortable.core.esm.js +184 -111
- data/node_modules/sortablejs/modular/sortable.esm.js +184 -111
- data/node_modules/sortablejs/package.json +3 -3
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d544979af086e1b51d9bc444a8df7915e8bfbb5408cd57bd810e895d82bb6248
|
4
|
+
data.tar.gz: df81a0cc285b349a82f5f74c16131ccf5b4729103c93aa7a7ea0f9c897791012
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db5a2631e57d734da3540471a07974d71a73d95ac013bc5d9dcd9185decc34602dd99dd110d6c3092971bf44096d92e9c26967ba33bd2c79b21a465179d7ea7f
|
7
|
+
data.tar.gz: 5fca1e9effe07e496bba47fb30ad6b9ff32e99a81b675812c0ae8c27cf51610e04616aa3d3d1b5cc5939dd1fd26cc1209a20c6a95ac7e4f4c41cc82e0fad88a4
|
@@ -17,6 +17,8 @@
|
|
17
17
|
// if there are no accordion sections on the browse level 2 page
|
18
18
|
// then it is a default page with one or two lists
|
19
19
|
return document.querySelectorAll('[data-track-count="accordionSection"]').length || document.querySelectorAll('main .govuk-list').length
|
20
|
+
case isCostOfLivingHub():
|
21
|
+
return document.querySelectorAll('[data-track-count="accordionSection"]').length
|
20
22
|
case isNewBrowsePage():
|
21
23
|
return document.querySelectorAll('[data-track-count="cardList"]').length
|
22
24
|
case isMainstreamBrowsePage():
|
@@ -51,6 +53,7 @@
|
|
51
53
|
case isDocumentCollectionPage():
|
52
54
|
return document.querySelectorAll('.document-collection .group-document-list li a').length
|
53
55
|
case isNewBrowsePageLevelTwo():
|
56
|
+
case isCostOfLivingHub():
|
54
57
|
return document.querySelectorAll('[data-track-count="contentLink"]').length
|
55
58
|
case isNewBrowsePage():
|
56
59
|
return document.querySelectorAll('[data-track-count="cardLink"]').length
|
@@ -108,6 +111,11 @@
|
|
108
111
|
getMetaAttribute(metaNavigationTypeSelector) === 'browse level 2'
|
109
112
|
}
|
110
113
|
|
114
|
+
function isCostOfLivingHub () {
|
115
|
+
return getMetaAttribute(metaApplicationSelector) === 'collections' &&
|
116
|
+
getMetaAttribute(metaNavigationTypeSelector) === 'cost of living hub'
|
117
|
+
}
|
118
|
+
|
111
119
|
function isNewBrowsePage () {
|
112
120
|
return getMetaAttribute(metaApplicationSelector) === 'collections' &&
|
113
121
|
(getMetaAttribute(metaNavigationTypeSelector) === 'browse level 0' ||
|
@@ -5,16 +5,16 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
|
|
5
5
|
(function (Modules) {
|
6
6
|
'use strict'
|
7
7
|
|
8
|
-
function
|
8
|
+
function Ga4EventTracker (module) {
|
9
9
|
this.module = module
|
10
10
|
this.trackingTrigger = 'data-ga4' // elements with this attribute get tracked
|
11
11
|
}
|
12
12
|
|
13
|
-
|
13
|
+
Ga4EventTracker.prototype.init = function () {
|
14
14
|
this.module.addEventListener('click', this.trackClick.bind(this), true) // useCapture must be true
|
15
15
|
}
|
16
16
|
|
17
|
-
|
17
|
+
Ga4EventTracker.prototype.trackClick = function (event) {
|
18
18
|
if (window.dataLayer) {
|
19
19
|
var target = this.findTrackingAttributes(event.target)
|
20
20
|
if (target) {
|
@@ -76,7 +76,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
|
|
76
76
|
}
|
77
77
|
}
|
78
78
|
|
79
|
-
|
79
|
+
Ga4EventTracker.prototype.findTrackingAttributes = function (clicked) {
|
80
80
|
if (clicked.hasAttribute('[' + this.trackingTrigger + ']')) {
|
81
81
|
return clicked
|
82
82
|
} else {
|
@@ -85,7 +85,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
|
|
85
85
|
}
|
86
86
|
|
87
87
|
// check if an attribute exists or contains the attribute
|
88
|
-
|
88
|
+
Ga4EventTracker.prototype.getClosestAttribute = function (clicked, attribute) {
|
89
89
|
var isAttributeOnElement = clicked.getAttribute(attribute)
|
90
90
|
var containsAttribute = clicked.querySelector('[' + attribute + ']')
|
91
91
|
|
@@ -96,5 +96,5 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
|
|
96
96
|
}
|
97
97
|
}
|
98
98
|
|
99
|
-
Modules.
|
99
|
+
Modules.Ga4EventTracker = Ga4EventTracker
|
100
100
|
})(window.GOVUK.Modules)
|
@@ -44,24 +44,26 @@
|
|
44
44
|
}
|
45
45
|
|
46
46
|
if (this.isMailToLink(href)) {
|
47
|
+
clickData.event_name = 'navigation'
|
47
48
|
clickData.type = 'email'
|
48
49
|
clickData.external = 'true'
|
49
50
|
} else if (this.isDownloadLink(href)) {
|
50
|
-
clickData.
|
51
|
-
clickData.
|
51
|
+
clickData.event_name = 'file_download'
|
52
|
+
clickData.type = this.isPreviewLink(href) ? 'preview' : 'generic download'
|
53
|
+
clickData.external = 'true'
|
52
54
|
} else if (this.isExternalLink(href)) {
|
55
|
+
clickData.event_name = 'navigation'
|
53
56
|
clickData.type = 'generic link'
|
54
57
|
clickData.external = 'true'
|
55
58
|
}
|
56
59
|
|
57
60
|
if (Object.keys(clickData).length > 0) {
|
58
|
-
clickData.event_name = 'navigation'
|
59
61
|
clickData.text = element.textContent.trim()
|
60
62
|
clickData.url = href
|
61
63
|
clickData.link_method = this.getClickType(event)
|
62
64
|
|
63
65
|
var schema = new window.GOVUK.analyticsGA4.Schemas().eventSchema()
|
64
|
-
schema.event = '
|
66
|
+
schema.event = 'event_data'
|
65
67
|
|
66
68
|
// get attributes from the clickData object to send to GA
|
67
69
|
// only allow it if it already exists in the schema
|
@@ -124,11 +126,23 @@
|
|
124
126
|
|
125
127
|
isExternalLink: function (href) {
|
126
128
|
var isInternalLink = this.hrefPointsToDomain(href, this.internalLinksDomain) || this.hrefPointsToDomain(href, this.internalLinksDomainWithoutWww)
|
127
|
-
if (!isInternalLink && !this.hrefIsRelative(href)) {
|
129
|
+
if (!isInternalLink && !this.hrefIsRelative(href) && !this.hrefIsAnchor(href)) {
|
128
130
|
return true
|
129
131
|
}
|
130
132
|
},
|
131
133
|
|
134
|
+
isPreviewLink: function (href) {
|
135
|
+
/* Regex looks for:
|
136
|
+
1. The file extension period (the character '.')
|
137
|
+
2. any alphanumeric characters (so we can match any file type such as jpg, pdf, mp4.)
|
138
|
+
3. the presence of '/preview'.
|
139
|
+
For example, .csv/preview or .mp4/preview will be matched.
|
140
|
+
Regex is used over JS string methods as this should work with anchor links, query string parameters and files that may have 'preview' in their name.
|
141
|
+
*/
|
142
|
+
var previewRegex = /\.\w+\/preview/i
|
143
|
+
return previewRegex.test(href)
|
144
|
+
},
|
145
|
+
|
132
146
|
hrefPointsToDomain: function (href, domain) {
|
133
147
|
var httpDomain = 'http://' + domain
|
134
148
|
var httpsDomain = 'https://' + domain
|
@@ -146,6 +160,10 @@
|
|
146
160
|
hrefIsRelative: function (href) {
|
147
161
|
// Checks that a link is relative, but is not a protocol relative url
|
148
162
|
return href[0] === '/' && href[1] !== '/'
|
163
|
+
},
|
164
|
+
|
165
|
+
hrefIsAnchor: function (href) {
|
166
|
+
return href[0] === '#'
|
149
167
|
}
|
150
168
|
}
|
151
169
|
|
@@ -9,7 +9,6 @@ window.GOVUK.Modules.GovukCheckboxes = window.GOVUKFrontend.Checkboxes;
|
|
9
9
|
this.$module = $module
|
10
10
|
this.$checkboxes = this.$module.querySelectorAll('input[type=checkbox]')
|
11
11
|
this.$nestedCheckboxes = this.$module.querySelectorAll('[data-nested=true] input[type=checkbox]')
|
12
|
-
this.$exclusiveCheckboxes = this.$module.querySelectorAll('[data-exclusive=true] input[type=checkbox]')
|
13
12
|
}
|
14
13
|
|
15
14
|
GemCheckboxes.prototype.init = function () {
|
@@ -22,10 +21,6 @@ window.GOVUK.Modules.GovukCheckboxes = window.GOVUKFrontend.Checkboxes;
|
|
22
21
|
for (i = 0; i < this.$nestedCheckboxes.length; i++) {
|
23
22
|
this.$nestedCheckboxes[i].addEventListener('change', this.handleNestedCheckboxChange.bind(this))
|
24
23
|
}
|
25
|
-
|
26
|
-
for (i = 0; i < this.$exclusiveCheckboxes.length; i++) {
|
27
|
-
this.$exclusiveCheckboxes[i].addEventListener('change', this.handleExclusiveCheckboxChange)
|
28
|
-
}
|
29
24
|
}
|
30
25
|
|
31
26
|
GemCheckboxes.prototype.handleCheckboxChange = function (event) {
|
@@ -95,23 +90,6 @@ window.GOVUK.Modules.GovukCheckboxes = window.GOVUKFrontend.Checkboxes;
|
|
95
90
|
}
|
96
91
|
}
|
97
92
|
|
98
|
-
GemCheckboxes.prototype.handleExclusiveCheckboxChange = function (event) {
|
99
|
-
var $currentCheckbox = event.target
|
100
|
-
var $checkboxes = $currentCheckbox.closest('.govuk-checkboxes')
|
101
|
-
var $exclusiveOption = $checkboxes.querySelector('input[type=checkbox][data-exclusive]')
|
102
|
-
var $nonExclusiveOptions = $checkboxes.querySelectorAll('input[type=checkbox]:not([data-exclusive])')
|
103
|
-
|
104
|
-
if ($currentCheckbox.getAttribute('data-exclusive') === 'true' && $currentCheckbox.checked === true) {
|
105
|
-
for (var i = 0; i < $nonExclusiveOptions.length; i++) {
|
106
|
-
$nonExclusiveOptions[i].checked = false
|
107
|
-
}
|
108
|
-
} else if ($currentCheckbox.getAttribute('data-exclusive') !== 'true' && $currentCheckbox.checked === true) {
|
109
|
-
if ($exclusiveOption) {
|
110
|
-
$exclusiveOption.checked = false
|
111
|
-
}
|
112
|
-
}
|
113
|
-
}
|
114
|
-
|
115
93
|
GemCheckboxes.prototype.applyAriaControlsAttributes = function ($scope) {
|
116
94
|
var $inputs = $scope.querySelectorAll('[data-controls]')
|
117
95
|
|
@@ -12,3 +12,10 @@
|
|
12
12
|
.gem-c-layout-footer .govuk-footer__list {
|
13
13
|
padding-bottom: govuk-spacing(7);
|
14
14
|
}
|
15
|
+
|
16
|
+
.gem-c-layout-footer .govuk-footer__list-item:nth-child(odd):last-child {
|
17
|
+
// If there are an uneven number of links in the
|
18
|
+
// footer this ensures the left column has more links than the
|
19
|
+
// the right column.
|
20
|
+
margin-bottom: 20px;
|
21
|
+
}
|
@@ -811,7 +811,7 @@ $button-pipe-colour: darken(govuk-colour("mid-grey"), 20%);
|
|
811
811
|
|
812
812
|
.gem-c-layout-super-navigation-header__navigation-second-items--topics {
|
813
813
|
@include govuk-media-query($from: "desktop") {
|
814
|
-
@include columns($items:
|
814
|
+
@include columns($items: 17, $columns: 2, $selector: "li", $flow: column);
|
815
815
|
}
|
816
816
|
}
|
817
817
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "rouge"
|
2
|
+
require "awesome_print"
|
2
3
|
|
3
4
|
module GovukPublishingComponents
|
4
5
|
class ComponentExample
|
@@ -29,8 +30,8 @@ module GovukPublishingComponents
|
|
29
30
|
end
|
30
31
|
|
31
32
|
def pretty_data
|
32
|
-
json_key_regex = /"(\w*)"
|
33
|
-
output =
|
33
|
+
json_key_regex = /"(\w*)"\s*:/ # matches quoted keys ending with a colon, i.e. "key":
|
34
|
+
output = data.awesome_inspect(indent: -2, index: false, plain: true).gsub("=>", ":").gsub(json_key_regex, '\1:')
|
34
35
|
|
35
36
|
quoted_string_regex = /"((?:[^"\\]|\\.)*)"/ # matches "some text" - ignores escaped quotes, i.e. \"
|
36
37
|
output.gsub(quoted_string_regex) do |group|
|
@@ -28,7 +28,30 @@
|
|
28
28
|
</div>
|
29
29
|
</div>
|
30
30
|
|
31
|
-
|
31
|
+
<% if @component_doc.other_examples.any? %>
|
32
|
+
<div class="component-doc__content-list">
|
33
|
+
<%
|
34
|
+
content_items = [
|
35
|
+
{
|
36
|
+
href: "#default",
|
37
|
+
text: "How it looks",
|
38
|
+
}
|
39
|
+
]
|
40
|
+
|
41
|
+
@component_doc.other_examples.each do | example |
|
42
|
+
content_items << {
|
43
|
+
href: "##{example.id}",
|
44
|
+
text: example.name
|
45
|
+
}
|
46
|
+
end
|
47
|
+
%>
|
48
|
+
<%= render "govuk_publishing_components/components/contents_list", {
|
49
|
+
contents: content_items
|
50
|
+
} %>
|
51
|
+
</div>
|
52
|
+
<% end %>
|
53
|
+
|
54
|
+
<h2 class="component-doc-h2" id="default">
|
32
55
|
<a href="<%= component_example_path(@component_doc.id, "default") %>" class="govuk-link">How it looks</a>
|
33
56
|
<small>(<a href="<%= component_preview_path(@component_doc.id, "default") %>" class="govuk-link">preview</a>)</small>
|
34
57
|
<small>(<a href="<%= component_preview_all_path(@component_doc.id) %>" class="govuk-link">preview all</a>)</small>
|
@@ -65,8 +88,9 @@
|
|
65
88
|
<% if @component_doc.other_examples.any? %>
|
66
89
|
<div class="examples">
|
67
90
|
<h2 class="component-doc-h2">Other examples</h2>
|
91
|
+
|
68
92
|
<% @component_doc.other_examples.each do |example| %>
|
69
|
-
<div class="component-example">
|
93
|
+
<div class="component-example" id="<%= example.id %>">
|
70
94
|
<h3 class="example-title">
|
71
95
|
<a href="<%= component_example_path(@component_doc.id, example.id) %>" class="govuk-link"><%= example.name %></a>
|
72
96
|
<small>(<a href="<%= component_preview_path(@component_doc.id, example.id) %>" class="govuk-link">preview</a>)</small>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
id = cb_helper.id
|
5
5
|
%>
|
6
6
|
|
7
|
-
<%= tag.div id: id, class: cb_helper.css_classes, data: { module: "gem-checkboxes" } do %>
|
7
|
+
<%= tag.div id: id, class: cb_helper.css_classes, data: { module: "gem-checkboxes govuk-checkboxes" } do %>
|
8
8
|
<% if cb_helper.should_have_fieldset %>
|
9
9
|
<% if cb_helper.heading_markup %>
|
10
10
|
<%= tag.fieldset class: "govuk-fieldset", "aria-describedby": cb_helper.fieldset_describedby do %>
|
@@ -24,8 +24,7 @@
|
|
24
24
|
|
25
25
|
<%= tag.ul class: cb_helper.list_classes, data: {
|
26
26
|
module: ('govuk-checkboxes' if cb_helper.has_conditional),
|
27
|
-
nested: ('true' if cb_helper.has_nested)
|
28
|
-
exclusive: ('true' if cb_helper.has_exclusive)
|
27
|
+
nested: ('true' if cb_helper.has_nested)
|
29
28
|
} do %>
|
30
29
|
<% cb_helper.items.each_with_index do |item, index| %>
|
31
30
|
<% if item === :or %>
|
@@ -103,3 +103,10 @@ examples:
|
|
103
103
|
name: "described"
|
104
104
|
rows: 2
|
105
105
|
describedby: "contextual-guidance"
|
106
|
+
with_data_attributes:
|
107
|
+
data:
|
108
|
+
label:
|
109
|
+
text: "This textarea has a data attribute"
|
110
|
+
name: "with_data_attrbutes"
|
111
|
+
data:
|
112
|
+
module: "some-awesome-module-here"
|
data/config/locales/en.yml
CHANGED
@@ -96,6 +96,8 @@ en:
|
|
96
96
|
href: "/browse/childcare-parenting"
|
97
97
|
- text: Citizenship and living in the UK
|
98
98
|
href: "/browse/citizenship"
|
99
|
+
- text: Cost of living support
|
100
|
+
href: "/cost-of-living"
|
99
101
|
- text: Crime, justice and the law
|
100
102
|
href: "/browse/justice"
|
101
103
|
- text: Disabled people
|
@@ -175,6 +177,8 @@ en:
|
|
175
177
|
href: "/browse/childcare-parenting"
|
176
178
|
- label: Citizenship and living in the UK
|
177
179
|
href: "/browse/citizenship"
|
180
|
+
- label: Cost of living support
|
181
|
+
href: "/cost-of-living"
|
178
182
|
- label: Crime, justice and the law
|
179
183
|
href: "/browse/justice"
|
180
184
|
- label: Disabled people
|
@@ -14,8 +14,7 @@ module GovukPublishingComponents
|
|
14
14
|
:id,
|
15
15
|
:hint_text,
|
16
16
|
:description,
|
17
|
-
:heading_caption
|
18
|
-
:has_exclusive
|
17
|
+
:heading_caption
|
19
18
|
|
20
19
|
def initialize(options)
|
21
20
|
@items = options[:items] || []
|
@@ -29,7 +28,6 @@ module GovukPublishingComponents
|
|
29
28
|
|
30
29
|
# check if any item is set as being conditional
|
31
30
|
@has_conditional = options[:items].any? { |item| item.is_a?(Hash) && item[:conditional] }
|
32
|
-
@has_exclusive = options[:items].any? { |item| item.is_a?(Hash) && item[:exclusive] }
|
33
31
|
@has_nested = options[:items].any? { |item| item.is_a?(Hash) && item[:items] }
|
34
32
|
|
35
33
|
@id = options[:id] || "checkboxes-#{SecureRandom.hex(4)}"
|
@@ -97,7 +95,7 @@ module GovukPublishingComponents
|
|
97
95
|
data = checkbox[:data_attributes] || {}
|
98
96
|
data[:controls] = controls
|
99
97
|
data["aria-controls"] = aria_controls
|
100
|
-
data[:
|
98
|
+
data[:behaviour] = "exclusive" if checkbox[:exclusive]
|
101
99
|
|
102
100
|
capture do
|
103
101
|
concat check_box_tag checkbox_name, checkbox[:value], checked, class: "govuk-checkboxes__input", id: checkbox_id, data: data
|