govuk_publishing_components 35.1.1 → 35.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/component_guide/application.js +1 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-core.js +34 -4
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js +20 -2
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/init-ga4.js +5 -0
- data/app/assets/javascripts/govuk_publishing_components/components/intervention.js +69 -0
- data/app/assets/javascripts/govuk_publishing_components/components/step-by-step-nav.js +5 -2
- data/app/assets/javascripts/govuk_publishing_components/lib/cookie-functions.js +1 -0
- data/app/assets/javascripts/govuk_publishing_components/vendor/lux/lux-reporter.js +430 -313
- data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +2 -3
- data/app/controllers/govuk_publishing_components/component_guide_controller.rb +1 -1
- data/app/models/govuk_publishing_components/audit_applications.rb +5 -1
- data/app/models/govuk_publishing_components/audit_comparer.rb +4 -4
- data/app/views/govuk_publishing_components/audit/_applications.html.erb +22 -4
- data/app/views/govuk_publishing_components/components/_accordion.html.erb +25 -1
- data/app/views/govuk_publishing_components/components/_intervention.html.erb +15 -7
- data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb +19 -5
- data/app/views/govuk_publishing_components/components/_step_by_step_nav.html.erb +23 -3
- data/app/views/govuk_publishing_components/components/_step_by_step_nav_related.html.erb +24 -4
- data/app/views/govuk_publishing_components/components/docs/intervention.yml +11 -6
- data/lib/govuk_publishing_components/presenters/component_wrapper_helper.rb +35 -12
- data/lib/govuk_publishing_components/presenters/intervention_helper.rb +16 -5
- data/lib/govuk_publishing_components/presenters/step_by_step_nav_helper.rb +0 -16
- data/lib/govuk_publishing_components/version.rb +1 -1
- metadata +5 -4
@@ -2,7 +2,6 @@
|
|
2
2
|
@import "mixins/prefixed-transform";
|
3
3
|
@import "mixins/grid-helper";
|
4
4
|
|
5
|
-
$icon-size: 20px;
|
6
5
|
$chevron-indent-spacing: 7px;
|
7
6
|
$black-bar-height: 50px;
|
8
7
|
$search-width-or-height: $black-bar-height;
|
@@ -343,9 +342,9 @@ $after-button-padding-left: govuk-spacing(4);
|
|
343
342
|
|
344
343
|
.gem-c-layout-super-navigation-header__search-item-link-icon,
|
345
344
|
.gem-c-layout-super-navigation-header__search-toggle-button-link-icon {
|
346
|
-
height:
|
345
|
+
height: 20px;
|
347
346
|
pointer-events: none;
|
348
|
-
width:
|
347
|
+
width: 21px;
|
349
348
|
}
|
350
349
|
|
351
350
|
// Search and popular content dropdown.
|
@@ -2,7 +2,7 @@ module GovukPublishingComponents
|
|
2
2
|
class ComponentGuideController < GovukPublishingComponents::ApplicationController
|
3
3
|
append_view_path File.join(Rails.root, "app", "views", GovukPublishingComponents::Config.component_directory_name)
|
4
4
|
|
5
|
-
MATCH_COMPONENTS = /(?<=govuk_publishing_components\/components\/)[\/a-zA-Z_-]+(?=['"])
|
5
|
+
MATCH_COMPONENTS = /(?<=govuk_publishing_components\/components\/)[\/a-zA-Z_-]+(?=['"])/
|
6
6
|
|
7
7
|
def index
|
8
8
|
@application_path = Rails.root
|
@@ -18,7 +18,9 @@ module GovukPublishingComponents
|
|
18
18
|
|
19
19
|
find_components = /(?<=govuk_publishing_components\/components\/)[a-zA-Z_-]+(?=['"])/
|
20
20
|
|
21
|
-
@find_all_stylesheets = /@import ["']{1}govuk_publishing_components\/all_components/
|
21
|
+
@find_all_stylesheets = /@import ["']{1}govuk_publishing_components\/all_components/ # if using the all stylesheets option
|
22
|
+
@find_individual_asset_model = /render_component_stylesheets/ # if using per page component asset loading
|
23
|
+
@uses_individual_asset_model = false
|
22
24
|
find_stylesheets = /(?<=@import ["']{1}govuk_publishing_components\/components\/)(?!print\/)+[a-zA-Z_-]+(?=['"])/
|
23
25
|
|
24
26
|
@find_all_javascripts = /\/\/ *= require govuk_publishing_components\/all_components/
|
@@ -63,6 +65,7 @@ module GovukPublishingComponents
|
|
63
65
|
jquery_references: @jquery_references.flatten.uniq.sort,
|
64
66
|
component_locations: @component_locations,
|
65
67
|
helper_references: @helper_references,
|
68
|
+
uses_individual_asset_model: @uses_individual_asset_model,
|
66
69
|
}
|
67
70
|
end
|
68
71
|
|
@@ -125,6 +128,7 @@ module GovukPublishingComponents
|
|
125
128
|
return %w[all] if src.match(@find_all_stylesheets) && type == "stylesheet"
|
126
129
|
return %w[all] if src.match(@find_all_javascripts) && type == "javascript"
|
127
130
|
|
131
|
+
@uses_individual_asset_model = true if src.match(@find_individual_asset_model) && type == "template"
|
128
132
|
matches = src.scan(find)
|
129
133
|
return [] unless matches.any?
|
130
134
|
|
@@ -54,15 +54,13 @@ module GovukPublishingComponents
|
|
54
54
|
|
55
55
|
results.each do |result|
|
56
56
|
if result[:application_found]
|
57
|
+
@current_uses_individual_asset_model = result[:uses_individual_asset_model]
|
57
58
|
application_uses_static = @applications_using_static.include?(result[:name])
|
58
59
|
templates = result[:components_found].find { |c| c[:location] == "template" }
|
59
60
|
stylesheets = result[:components_found].find { |c| c[:location] == "stylesheet" }
|
60
61
|
javascripts = result[:components_found].find { |c| c[:location] == "javascript" }
|
61
62
|
ruby = result[:components_found].find { |c| c[:location] == "ruby" }
|
62
63
|
|
63
|
-
@all_stylesheets = true if stylesheets[:components].include?("all")
|
64
|
-
@all_javascripts = true if javascripts[:components].include?("all")
|
65
|
-
|
66
64
|
templates[:components] = include_any_components_within_components(templates[:components])
|
67
65
|
|
68
66
|
warnings = []
|
@@ -103,6 +101,7 @@ module GovukPublishingComponents
|
|
103
101
|
jquery_references: result[:jquery_references],
|
104
102
|
component_locations: result[:component_locations],
|
105
103
|
helper_references: result[:helper_references],
|
104
|
+
uses_individual_asset_model: result[:uses_individual_asset_model],
|
106
105
|
}
|
107
106
|
else
|
108
107
|
data << {
|
@@ -161,7 +160,8 @@ module GovukPublishingComponents
|
|
161
160
|
|
162
161
|
check_static = @static_data && second_location != "code"
|
163
162
|
asset_in_static = asset_already_in_static(second_location, component) if check_static
|
164
|
-
|
163
|
+
suppress_warning = @current_uses_individual_asset_model && second_location == "stylesheet"
|
164
|
+
raise_warning = asset_in_gem && !asset_in_static && !suppress_warning
|
165
165
|
|
166
166
|
# this raises a warning if the asset exists and isn't included either in the application or static
|
167
167
|
warnings << create_warning(component, "Included in #{first_location} but not #{second_location}") if raise_warning
|
@@ -37,8 +37,24 @@
|
|
37
37
|
<% github_link = 'https://github.com/alphagov/' + application[:name] + '/blob/main/' %>
|
38
38
|
|
39
39
|
<% if @other_applications %>
|
40
|
+
<% if application[:uses_individual_asset_model] %>
|
41
|
+
<div class="govuk-warning-text">
|
42
|
+
<span class="govuk-warning-text__icon" aria-hidden="true">!</span>
|
43
|
+
<strong class="govuk-warning-text__text">
|
44
|
+
<span class="govuk-warning-text__assistive">Warning</span>
|
45
|
+
This application uses <a class="govuk-link" href="https://github.com/alphagov/govuk_publishing_components/blob/main/docs/set-up-individual-component-css-loading.md">per page asset loading</a> for components. Warnings about missing stylesheets have been suppressed.
|
46
|
+
</strong>
|
47
|
+
</div>
|
48
|
+
<% end %>
|
49
|
+
|
40
50
|
<% if application[:uses_static] %>
|
41
|
-
<
|
51
|
+
<div class="govuk-warning-text">
|
52
|
+
<span class="govuk-warning-text__icon" aria-hidden="true">!</span>
|
53
|
+
<strong class="govuk-warning-text__text">
|
54
|
+
<span class="govuk-warning-text__assistive">Warning</span>
|
55
|
+
This application uses <a href="https://github.com/alphagov/static" class="govuk-link">static</a>, which can contain assets for components used in more than one application. Warnings for missing component assets in this application that are already included in static have been suppressed.
|
56
|
+
</strong>
|
57
|
+
</div>
|
42
58
|
<% end %>
|
43
59
|
|
44
60
|
<% application[:warnings].each do |warning| %>
|
@@ -67,6 +83,8 @@
|
|
67
83
|
<dd class="govuk-summary-list__value">
|
68
84
|
<% if item[:value].length > 0 %>
|
69
85
|
<%= item[:value].join(", ") %>
|
86
|
+
<% elsif application[:uses_individual_asset_model] && item[:name] == "In stylesheets" %>
|
87
|
+
Uses per page component asset loading
|
70
88
|
<% else %>
|
71
89
|
None
|
72
90
|
<% end %>
|
@@ -77,13 +95,13 @@
|
|
77
95
|
|
78
96
|
<% if application[:gem_style_references].any? %>
|
79
97
|
<%= render "govuk_publishing_components/components/heading", {
|
80
|
-
text: "Component references",
|
98
|
+
text: "Component references (#{application[:gem_style_references].length})",
|
81
99
|
font_size: "m",
|
82
100
|
margin_bottom: 4,
|
83
101
|
heading_level: 3,
|
84
102
|
} %>
|
85
103
|
|
86
|
-
<p class="govuk-body">This shows instances of `gem-c-` classes found in the application.
|
104
|
+
<p class="govuk-body">This shows instances of `gem-c-` classes found in the application. This could be a style override or hard coded component markup, which is a violation of our principle of <a href="https://github.com/alphagov/govuk_publishing_components/blob/main/docs/component_principles.md#a-component-is-isolated-when" class="govuk-link">component isolation</a>.</p>
|
87
105
|
<ul class="govuk-list govuk-list--bullet">
|
88
106
|
<% application[:gem_style_references].each do |ref| %>
|
89
107
|
<li>
|
@@ -95,7 +113,7 @@
|
|
95
113
|
|
96
114
|
<% if application[:jquery_references].any? %>
|
97
115
|
<%= render "govuk_publishing_components/components/heading", {
|
98
|
-
text: "jQuery references",
|
116
|
+
text: "jQuery references (#{application[:jquery_references].length})",
|
99
117
|
font_size: "m",
|
100
118
|
margin_bottom: 4,
|
101
119
|
heading_level: 3,
|
@@ -37,6 +37,7 @@
|
|
37
37
|
index = i + 1
|
38
38
|
|
39
39
|
item[:data_attributes] ||= nil
|
40
|
+
ga4_link_data_attributes ||= nil
|
40
41
|
|
41
42
|
if ga4_tracking
|
42
43
|
item[:data_attributes] ||= {}
|
@@ -49,6 +50,23 @@
|
|
49
50
|
index_section_count: items.length,
|
50
51
|
},
|
51
52
|
}.to_json
|
53
|
+
|
54
|
+
# These attributes have been created separately from the item[:data_attributes]
|
55
|
+
# object in order to keep them from colliding with GA4 event tracking and UA
|
56
|
+
# tracking attributes
|
57
|
+
ga4_link_data_attributes = {}
|
58
|
+
ga4_link_data_attributes[:module] = "ga4-link-tracker"
|
59
|
+
ga4_link_data_attributes[:ga4_tracks_links_only] = ""
|
60
|
+
ga4_link_data_attributes[:ga4_set_indexes] = ""
|
61
|
+
ga4_link_data_attributes[:ga4_link] = {
|
62
|
+
event_name: "navigation",
|
63
|
+
type: "accordion",
|
64
|
+
section: item[:heading][:text],
|
65
|
+
index: {
|
66
|
+
index_section: index,
|
67
|
+
index_section_count: (items.length),
|
68
|
+
}
|
69
|
+
}.to_json
|
52
70
|
end
|
53
71
|
|
54
72
|
section_classes = %w(govuk-accordion__section)
|
@@ -74,7 +92,13 @@
|
|
74
92
|
%>
|
75
93
|
<%= tag.div(item[:summary][:text], id: "#{id}-summary-#{index}", class: summary_classes) if item[:summary].present? %>
|
76
94
|
<% end %>
|
77
|
-
<%= tag.div(
|
95
|
+
<%= tag.div(
|
96
|
+
item[:content][:html],
|
97
|
+
id: "#{id}-content-#{index}",
|
98
|
+
class: "govuk-accordion__section-content",
|
99
|
+
'aria-labelledby': "#{id}-heading-#{index}",
|
100
|
+
data: ga4_link_data_attributes
|
101
|
+
) %>
|
78
102
|
<% end %>
|
79
103
|
<% end %>
|
80
104
|
<% end %>
|
@@ -1,6 +1,7 @@
|
|
1
1
|
<%
|
2
2
|
add_gem_component_stylesheet("intervention")
|
3
3
|
|
4
|
+
name ||= ""
|
4
5
|
dismiss_text ||= false
|
5
6
|
suggestion_link_text ||= false
|
6
7
|
suggestion_link_url ||= false
|
@@ -10,16 +11,23 @@
|
|
10
11
|
|
11
12
|
data_attributes ||= {}
|
12
13
|
suggestion_data_attributes ||= {}
|
13
|
-
|
14
|
+
data_attributes[:module] = "intervention"
|
15
|
+
data_attributes["intervention-name"] = name
|
14
16
|
|
15
17
|
aria_attributes ||= {}
|
16
18
|
aria_attributes[:label] = 'Intervention'
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
options = {
|
21
|
+
name: name,
|
22
|
+
dismiss_text: dismiss_text,
|
23
|
+
params: request.params,
|
24
|
+
query_string: request.query_string,
|
25
|
+
suggestion_text: suggestion_text,
|
26
|
+
suggestion_link_text: suggestion_link_text,
|
27
|
+
suggestion_link_url: suggestion_link_url,
|
28
|
+
}
|
21
29
|
|
22
|
-
intervention_helper = GovukPublishingComponents::Presenters::InterventionHelper.new(
|
30
|
+
intervention_helper = GovukPublishingComponents::Presenters::InterventionHelper.new(options)
|
23
31
|
dismiss_href = intervention_helper.dismiss_link
|
24
32
|
|
25
33
|
suggestion_tag_options = {
|
@@ -44,7 +52,7 @@
|
|
44
52
|
}
|
45
53
|
section_options.merge!({ hidden: true }) if hide
|
46
54
|
%>
|
47
|
-
<% if
|
55
|
+
<% if intervention_helper.show? %>
|
48
56
|
<%= tag.section **section_options do %>
|
49
57
|
<p class="govuk-body">
|
50
58
|
<%= tag.span suggestion_text, class: "gem-c-intervention__textwrapper" if suggestion_text %>
|
@@ -55,7 +63,7 @@
|
|
55
63
|
|
56
64
|
<% if dismiss_text %>
|
57
65
|
<p class="govuk-body">
|
58
|
-
<%= tag.a class: "govuk-link", href: dismiss_href
|
66
|
+
<%= tag.a class: "govuk-link js-dismiss-link", href: dismiss_href do %>
|
59
67
|
<svg class="gem-c-intervention__dismiss-icon"
|
60
68
|
width="19" height="19" viewBox="0 0 19 19"
|
61
69
|
aria-hidden="true"
|
data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb
CHANGED
@@ -43,7 +43,9 @@
|
|
43
43
|
"external": "false",
|
44
44
|
"text": "GOV.UK",
|
45
45
|
"section": "Logo",
|
46
|
-
"index":
|
46
|
+
"index": {
|
47
|
+
"index_section": 0,
|
48
|
+
},
|
47
49
|
"index_total": navigation_links_length
|
48
50
|
}.to_json %>"
|
49
51
|
>
|
@@ -128,7 +130,9 @@
|
|
128
130
|
event_name: "select_content",
|
129
131
|
type: "header menu bar",
|
130
132
|
text: link[:label],
|
131
|
-
index:
|
133
|
+
index: {
|
134
|
+
index_section: 1,
|
135
|
+
},
|
132
136
|
index_total: 2,
|
133
137
|
section: link[:label]
|
134
138
|
}
|
@@ -159,7 +163,9 @@
|
|
159
163
|
"event_name": "select_content",
|
160
164
|
"type": "header menu bar",
|
161
165
|
"text": "Search",
|
162
|
-
"index":
|
166
|
+
"index": {
|
167
|
+
"index_section": 2,
|
168
|
+
},
|
163
169
|
"index_total": 2,
|
164
170
|
"section": "Search"
|
165
171
|
}.to_json %>"
|
@@ -238,7 +244,11 @@
|
|
238
244
|
ga4_link: {
|
239
245
|
"event_name": "navigation",
|
240
246
|
"type": "header menu bar",
|
241
|
-
"index":
|
247
|
+
"index": {
|
248
|
+
"index_section": column_index + 1,
|
249
|
+
"index_link": index + 1,
|
250
|
+
"index_section_count": 4,
|
251
|
+
},
|
242
252
|
"index_total": navigation_links_length,
|
243
253
|
"section": column[:label],
|
244
254
|
}
|
@@ -308,7 +318,11 @@
|
|
308
318
|
ga4_link: {
|
309
319
|
"event_name": "navigation",
|
310
320
|
"type": "header menu bar",
|
311
|
-
"index":
|
321
|
+
"index": {
|
322
|
+
"index_section": 4,
|
323
|
+
"index_link": index + 1,
|
324
|
+
"index_section_count": 4,
|
325
|
+
},
|
312
326
|
"index_total": navigation_links_length,
|
313
327
|
"section": popular_links_heading,
|
314
328
|
}
|
@@ -22,7 +22,7 @@
|
|
22
22
|
%>
|
23
23
|
<% if steps %>
|
24
24
|
<div
|
25
|
-
data-module="gemstepnav<% if ga4_tracking %> ga4-event-tracker
|
25
|
+
data-module="gemstepnav<% if ga4_tracking %> ga4-event-tracker<% end %>"
|
26
26
|
<%= "data-ga4-expandable" if ga4_tracking %>
|
27
27
|
class="gem-c-step-nav js-hidden <% if small %>govuk-!-display-none-print<% end %> <% unless small %>gem-c-step-nav--large<% end %>"
|
28
28
|
<%= "data-remember" if remember_last_step %>
|
@@ -73,7 +73,27 @@
|
|
73
73
|
<% end %>
|
74
74
|
</div>
|
75
75
|
|
76
|
-
|
76
|
+
<%
|
77
|
+
ga4_link_data = {}
|
78
|
+
|
79
|
+
if ga4_tracking
|
80
|
+
ga4_link_data = {
|
81
|
+
"module": "ga4-link-tracker",
|
82
|
+
"ga4-track-links-only": "",
|
83
|
+
"ga4-set-indexes": "",
|
84
|
+
"ga4-link": {
|
85
|
+
"event_name": "navigation",
|
86
|
+
"type": "step by step",
|
87
|
+
"index": {
|
88
|
+
"index_section": step_index + 1
|
89
|
+
},
|
90
|
+
"section": step[:title]
|
91
|
+
}.to_json
|
92
|
+
}
|
93
|
+
end
|
94
|
+
%>
|
95
|
+
|
96
|
+
<%= tag.div(class: "gem-c-step-nav__panel js-panel", id: "step-panel-#{id}-#{step_index + 1}", data: ga4_link_data) do %>
|
77
97
|
<%
|
78
98
|
in_substep = false
|
79
99
|
options[:step_nav_content_id] = step_nav_content_id
|
@@ -91,7 +111,7 @@
|
|
91
111
|
end
|
92
112
|
%>
|
93
113
|
<% end %>
|
94
|
-
|
114
|
+
<% end %>
|
95
115
|
|
96
116
|
</li>
|
97
117
|
<% end %>
|
@@ -23,8 +23,18 @@
|
|
23
23
|
data-track-dimension="<%= links[0][:text] %>"
|
24
24
|
data-track-dimension-index="29"
|
25
25
|
data-track-options='{"dimension96" : "<%= links[0][:tracking_id] %>" }'
|
26
|
-
<% if ga4_tracking
|
27
|
-
|
26
|
+
<% if ga4_tracking
|
27
|
+
ga4_attributes = {
|
28
|
+
event_name: "navigation",
|
29
|
+
type: "related content",
|
30
|
+
index:{
|
31
|
+
"index_link": "1"
|
32
|
+
},
|
33
|
+
index_total: "1",
|
34
|
+
section: "Part of",
|
35
|
+
}.to_json
|
36
|
+
%>
|
37
|
+
data-ga4-link="<%= ga4_attributes %>"
|
28
38
|
<% end %>
|
29
39
|
>
|
30
40
|
<%= links[0][:text] %>
|
@@ -43,8 +53,18 @@
|
|
43
53
|
data-track-dimension="<%= link[:text] %>"
|
44
54
|
data-track-dimension-index="29"
|
45
55
|
data-track-options='{"dimension96" : "<%= link[:tracking_id] %>" }'
|
46
|
-
<% if ga4_tracking
|
47
|
-
|
56
|
+
<% if ga4_tracking
|
57
|
+
ga4_attributes = {
|
58
|
+
event_name: "navigation",
|
59
|
+
type: "related content",
|
60
|
+
index:{
|
61
|
+
"index_link": (index + 1).to_s
|
62
|
+
},
|
63
|
+
index_total: (links.length).to_s,
|
64
|
+
section: "Part of",
|
65
|
+
}.to_json
|
66
|
+
%>
|
67
|
+
data-ga4-link="<%= ga4_attributes %>"
|
48
68
|
<% end %>
|
49
69
|
>
|
50
70
|
<%= link[:text] %>
|
@@ -6,7 +6,10 @@ body: |
|
|
6
6
|
that would be useful to them. This component would be used to add this personalised content and would
|
7
7
|
indicate to the user that this is not normally part of the page, but has been added for them specifically.
|
8
8
|
|
9
|
-
The dismiss link
|
9
|
+
The dismiss link works without Javascript by pointing to the current URL with the "hide-intervention"
|
10
|
+
query string parameter set to "true". It's progressively enhanced and sets a cookie to remember that
|
11
|
+
the user has dismissed the banner before. The cookie requires a "name" parameter, the value of which
|
12
|
+
is stored in the cookie to distinguish which campaign banner the user has dismissed.
|
10
13
|
|
11
14
|
accessibility_criteria: |
|
12
15
|
The intervention component must:
|
@@ -30,20 +33,20 @@ examples:
|
|
30
33
|
suggestion_link_url: /travel-abroad
|
31
34
|
|
32
35
|
with_dismiss_link:
|
36
|
+
description: |
|
37
|
+
Name is required in order to set a cookie. The name value should be distinct to the campaign for the banner,
|
38
|
+
so that other banners using this component are not hidden by accident.
|
33
39
|
data:
|
34
40
|
suggestion_text: You should renew your permit every 6 months.
|
35
41
|
dismiss_text: Hide this suggestion
|
36
|
-
|
37
|
-
with_suggestion_link_only:
|
38
|
-
data:
|
39
|
-
suggestion_link_text: You can now apply for a permit online.
|
40
|
-
suggestion_link_url: /permit
|
42
|
+
name: campaign-name
|
41
43
|
|
42
44
|
with_hide:
|
43
45
|
description: |
|
44
46
|
This example is for when we want to hide by default and display to the user based on some logic,
|
45
47
|
either in the backend or with Javascript.
|
46
48
|
data:
|
49
|
+
suggestion_text: You should renew your permit every 6 months.
|
47
50
|
suggestion_link_text: You may be invited to fill in a questionnaire
|
48
51
|
suggestion_link_url: /questionnaire
|
49
52
|
hide: true
|
@@ -55,6 +58,7 @@ examples:
|
|
55
58
|
Link text should tell the user that the link opens in a new tab.
|
56
59
|
Note: "(opens in a new tab)" is added to link text if the phrase isn't included.
|
57
60
|
data:
|
61
|
+
suggestion_text: You should renew your permit every 6 months.
|
58
62
|
suggestion_link_text: You can now apply for a permit online
|
59
63
|
suggestion_link_url: www.google.com/permit
|
60
64
|
new_tab: true
|
@@ -76,6 +80,7 @@ examples:
|
|
76
80
|
track-dimension-index: 29
|
77
81
|
track-label: clicked suggestion
|
78
82
|
dismiss_text: Hide this suggestion
|
83
|
+
name: another-campaign-name
|
79
84
|
dismiss_data_attributes:
|
80
85
|
track-category: interventionBanner
|
81
86
|
track-action: interventionDismissed
|
@@ -5,6 +5,7 @@ module GovukPublishingComponents
|
|
5
5
|
@options = options
|
6
6
|
|
7
7
|
check_id_is_valid(@options[:id]) if @options.include?(:id)
|
8
|
+
check_data_attributes_are_valid(@options[:data_attributes]) if @options.include?(:data_attributes)
|
8
9
|
check_classes_are_valid(@options[:classes]) if @options.include?(:classes)
|
9
10
|
check_aria_is_valid(@options[:aria]) if @options.include?(:aria)
|
10
11
|
check_role_is_valid(@options[:role]) if @options.include?(:role)
|
@@ -13,11 +14,11 @@ module GovukPublishingComponents
|
|
13
14
|
def all_attributes
|
14
15
|
attributes = {}
|
15
16
|
|
16
|
-
attributes[:id] = @options[:id]
|
17
|
-
attributes[:data] = @options[:data_attributes]
|
18
|
-
attributes[:aria] = @options[:aria]
|
19
|
-
attributes[:class] = @options[:classes]
|
20
|
-
attributes[:role] = @options[:role]
|
17
|
+
attributes[:id] = @options[:id] unless @options[:id].blank?
|
18
|
+
attributes[:data] = @options[:data_attributes] unless @options[:data_attributes].blank?
|
19
|
+
attributes[:aria] = @options[:aria] unless @options[:aria].blank?
|
20
|
+
attributes[:class] = @options[:classes] unless @options[:classes].blank?
|
21
|
+
attributes[:role] = @options[:role] unless @options[:role].blank?
|
21
22
|
|
22
23
|
attributes
|
23
24
|
end
|
@@ -33,6 +34,7 @@ module GovukPublishingComponents
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def add_data_attribute(attributes)
|
37
|
+
check_data_attributes_are_valid(attributes)
|
36
38
|
extend_object(:data_attributes, attributes)
|
37
39
|
end
|
38
40
|
|
@@ -49,29 +51,50 @@ module GovukPublishingComponents
|
|
49
51
|
private
|
50
52
|
|
51
53
|
def check_id_is_valid(id)
|
52
|
-
|
54
|
+
return if id.blank?
|
55
|
+
|
56
|
+
raise(ArgumentError, "Id (#{id}) cannot start with a number or contain whitespace and can only contain letters, digits, `_` and `-`") unless /^[a-zA-Z][\w:-]*$/.match?(id)
|
57
|
+
end
|
58
|
+
|
59
|
+
def check_data_attributes_are_valid(attributes)
|
60
|
+
return if attributes.blank?
|
61
|
+
|
62
|
+
attributes_keys = attributes.map { |key, _| key.to_s }
|
63
|
+
invalid_attributes = attributes_keys.map { |a| a if /^(xml)/.match?(a) || /[A-Z :]+/.match?(a) }.compact
|
64
|
+
|
65
|
+
raise(ArgumentError, "Data attributes (#{invalid_attributes.join(', ')}) cannot contain capitals, spaces or colons, or start with 'xml'") if invalid_attributes.any?
|
53
66
|
end
|
54
67
|
|
55
68
|
def check_classes_are_valid(classes)
|
56
|
-
|
57
|
-
|
58
|
-
|
69
|
+
return if classes.blank?
|
70
|
+
|
71
|
+
class_array = classes.split(" ")
|
72
|
+
unless class_array.all? { |c| c.start_with?("js-", "gem-c-", "govuk-", "brand--") }
|
73
|
+
raise(ArgumentError, "Classes (#{classes}) must be prefixed with `js-`")
|
59
74
|
end
|
60
75
|
end
|
61
76
|
|
62
77
|
def check_aria_is_valid(attributes)
|
78
|
+
return if attributes.blank?
|
79
|
+
|
63
80
|
arias = %w[activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby description details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext]
|
64
81
|
|
65
|
-
|
66
|
-
|
82
|
+
# array keys are immutable so we have to do this to make a copy, in order to
|
83
|
+
# subtract valid aria attributes from invalid in the error message below
|
84
|
+
attributes_keys = attributes.map { |key, _| key.to_s }
|
85
|
+
|
86
|
+
unless attributes_keys.all? { |key| arias.include? key }
|
87
|
+
raise(ArgumentError, "Aria attribute (#{(attributes_keys - arias).join(', ')}) not recognised")
|
67
88
|
end
|
68
89
|
end
|
69
90
|
|
70
91
|
def check_role_is_valid(role)
|
92
|
+
return if role.blank?
|
93
|
+
|
71
94
|
roles = %w[alert alertdialog application article associationlist associationlistitemkey associationlistitemvalue banner blockquote caption cell code columnheader combobox complementary contentinfo definition deletion dialog directory document emphasis feed figure form group heading img insertion list listitem log main marquee math menu menubar meter navigation none note paragraph presentation region row rowgroup rowheader scrollbar search searchbox separator separator slider spinbutton status strong subscript superscript switch tab table tablist tabpanel term time timer toolbar tooltip tree treegrid treeitem]
|
72
95
|
role = role.split(" ") # can have more than one role
|
73
96
|
unless role.all? { |r| roles.include? r }
|
74
|
-
raise(ArgumentError, "Role attribute is not recognised")
|
97
|
+
raise(ArgumentError, "Role attribute (#{(role - roles).join(', ')}) is not recognised")
|
75
98
|
end
|
76
99
|
end
|
77
100
|
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module GovukPublishingComponents
|
2
2
|
module Presenters
|
3
3
|
class InterventionHelper
|
4
|
-
def initialize(
|
4
|
+
def initialize(options = {})
|
5
|
+
@name = options[:name]
|
6
|
+
@dismiss_text = options[:dismiss_text]
|
5
7
|
@accessible_text_suffix = I18n.t("components.intervention.accessible_link_text_suffix")
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@
|
8
|
+
@params = options[:params]
|
9
|
+
@query_string = options[:query_string]
|
10
|
+
@suggestion_text = options[:suggestion_text]
|
11
|
+
@suggestion_link_text = options[:suggestion_link_text]
|
12
|
+
@suggestion_link_url = options[:suggestion_link_url]
|
9
13
|
end
|
10
14
|
|
11
15
|
def accessible_text
|
@@ -29,9 +33,16 @@ module GovukPublishingComponents
|
|
29
33
|
rel
|
30
34
|
end
|
31
35
|
|
36
|
+
def show?
|
37
|
+
return false if params["hide-intervention"] == "true"
|
38
|
+
return false if @dismiss_text && @name.blank?
|
39
|
+
|
40
|
+
@suggestion_text || (@suggestion_link_text && @suggestion_link_url)
|
41
|
+
end
|
42
|
+
|
32
43
|
private
|
33
44
|
|
34
|
-
attr_reader :accessible_text_suffix, :query_string, :suggestion_link_text, :suggestion_link_url
|
45
|
+
attr_reader :accessible_text_suffix, :query_string, :params, :suggestion_text, :suggestion_link_text, :suggestion_link_url
|
35
46
|
end
|
36
47
|
end
|
37
48
|
end
|
@@ -46,7 +46,6 @@ module GovukPublishingComponents
|
|
46
46
|
:li,
|
47
47
|
class: "gem-c-step-nav__list-item js-list-item #{link_active(contents[:active])}",
|
48
48
|
) do
|
49
|
-
@options[:ga4_index_total] = element[:contents].length if @options[:ga4_tracking]
|
50
49
|
create_list_item_content(contents)
|
51
50
|
end,
|
52
51
|
)
|
@@ -65,26 +64,11 @@ module GovukPublishingComponents
|
|
65
64
|
concat create_context(link[:context])
|
66
65
|
end
|
67
66
|
|
68
|
-
ga4_link_data ||= nil
|
69
|
-
if @options[:ga4_tracking]
|
70
|
-
ga4_link_data = {
|
71
|
-
"event_name": "navigation",
|
72
|
-
"type": "step by step",
|
73
|
-
"index": {
|
74
|
-
"index_section": (@options[:step_index] + 1).to_s,
|
75
|
-
"index_link": @link_index.to_s,
|
76
|
-
},
|
77
|
-
"index_total": @options[:ga4_index_total].to_s,
|
78
|
-
"section": @options[:step_title],
|
79
|
-
}.to_json
|
80
|
-
end
|
81
|
-
|
82
67
|
link_to(
|
83
68
|
href,
|
84
69
|
rel: ("external" if href.start_with?("http")),
|
85
70
|
data: {
|
86
71
|
position: "#{@options[:step_index] + 1}.#{@link_index}",
|
87
|
-
ga4_link: ga4_link_data,
|
88
72
|
},
|
89
73
|
class: "gem-c-step-nav__link js-link",
|
90
74
|
) do
|