govuk_publishing_components 21.55.4 → 21.57.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/components/print-link.js +14 -0
  3. data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +1 -0
  4. data/app/assets/stylesheets/govuk_publishing_components/component_support.scss +1 -0
  5. data/app/assets/stylesheets/govuk_publishing_components/components/_action-link.scss +11 -5
  6. data/app/assets/stylesheets/govuk_publishing_components/components/_cookie-banner.scss +4 -0
  7. data/app/assets/stylesheets/govuk_publishing_components/components/_input.scss +9 -5
  8. data/app/assets/stylesheets/govuk_publishing_components/components/_print-link.scss +52 -0
  9. data/app/assets/stylesheets/govuk_publishing_components/components/_summary-list.scss +18 -5
  10. data/app/assets/stylesheets/govuk_publishing_components/components/helpers/_link.scss +17 -0
  11. data/app/assets/stylesheets/govuk_publishing_components/components/print/_govspeak.scss +5 -1
  12. data/app/views/govuk_publishing_components/components/_action_link.html.erb +2 -0
  13. data/app/views/govuk_publishing_components/components/_contextual_breadcrumbs.html.erb +11 -7
  14. data/app/views/govuk_publishing_components/components/_cookie_banner.html.erb +3 -1
  15. data/app/views/govuk_publishing_components/components/_input.html.erb +3 -4
  16. data/app/views/govuk_publishing_components/components/_print_link.html.erb +27 -0
  17. data/app/views/govuk_publishing_components/components/_summary_list.html.erb +34 -14
  18. data/app/views/govuk_publishing_components/components/docs/action_link.yml +5 -0
  19. data/app/views/govuk_publishing_components/components/docs/input.yml +9 -1
  20. data/app/views/govuk_publishing_components/components/docs/print_link.yml +24 -0
  21. data/app/views/govuk_publishing_components/components/docs/summary_list.yml +27 -0
  22. data/config/locales/en.yml +5 -0
  23. data/lib/govuk_publishing_components.rb +2 -1
  24. data/lib/govuk_publishing_components/presenters/breadcrumb_selector.rb +50 -42
  25. data/lib/govuk_publishing_components/presenters/content_breadcrumbs_based_on_ancestors.rb +41 -0
  26. data/lib/govuk_publishing_components/presenters/content_breadcrumbs_based_on_priority.rb +1 -0
  27. data/lib/govuk_publishing_components/presenters/content_breadcrumbs_based_on_taxons.rb +4 -0
  28. data/lib/govuk_publishing_components/presenters/content_breadcrumbs_based_on_topic.rb +38 -0
  29. data/lib/govuk_publishing_components/presenters/contextual_navigation.rb +15 -4
  30. data/lib/govuk_publishing_components/presenters/page_with_step_by_step_navigation.rb +3 -1
  31. data/lib/govuk_publishing_components/presenters/related_navigation_helper.rb +18 -17
  32. data/lib/govuk_publishing_components/version.rb +1 -1
  33. data/node_modules/axe-core/CHANGELOG.md +11 -0
  34. data/node_modules/axe-core/axe.js +36 -9
  35. data/node_modules/axe-core/axe.min.js +2 -2
  36. data/node_modules/axe-core/bower.json +1 -1
  37. data/node_modules/axe-core/lib/checks/color/color-contrast.js +2 -2
  38. data/node_modules/axe-core/lib/checks/lists/listitem.js +1 -1
  39. data/node_modules/axe-core/lib/checks/mobile/meta-viewport-scale.js +3 -0
  40. data/node_modules/axe-core/lib/commons/dom/is-visible.js +37 -19
  41. data/node_modules/axe-core/lib/core/public/configure.js +26 -0
  42. data/node_modules/axe-core/lib/rules/aria-input-field-name.json +1 -1
  43. data/node_modules/axe-core/package.json +12 -12
  44. data/node_modules/axe-core/sri-history.json +4 -0
  45. metadata +9 -3
  46. data/lib/govuk_publishing_components/presenters/content_breadcrumbs_based_on_parent.rb +0 -39
@@ -132,6 +132,14 @@ examples:
132
132
  text: "What is your name?"
133
133
  name: "name"
134
134
  heading_size: "l"
135
+ with_prefix:
136
+ description: To help users understand how the input should look like. Often used for units of measurement.
137
+ data:
138
+ label:
139
+ text: "Cost, in pounds"
140
+ name: "cost"
141
+ width: 10
142
+ prefix: "£"
135
143
  with_suffix:
136
144
  description: To help users understand how the input should look like. Often used for units of measurement.
137
145
  data:
@@ -145,7 +153,7 @@ examples:
145
153
  data:
146
154
  label:
147
155
  text: "Cost per item, in pounds"
148
- name: "Cost-per-item"
156
+ name: "cost-per-item"
149
157
  width: 10
150
158
  prefix: "£"
151
159
  suffix: "per item"
@@ -0,0 +1,24 @@
1
+ name: Print link
2
+ description: A link with a print icon to help users print the current page
3
+ body: |
4
+ This component renders two different outputs depending on whether a `href` is specified. By default, when no `href` is given, the component renders as a button and triggers a print action via JavaScript. In this case the component is hidden in environments where JavaScript is disabled and can be used as a progressive enhancement. When a `href` is specified the component renders as an anchor tag and navigates to that `href` without JavaScript, suitable for applications which have paths that trigger a print event on load.
5
+ accessibility_criteria: |
6
+ - The print icon must be presentational and ignored by screen readers.
7
+ shared_accessibility_criteria:
8
+ - link
9
+ examples:
10
+ default:
11
+ description: This component calls `print()` via the browser's DOM API. By default it relies on JavaScript and is not shown in environments where JavaScript is disabled. The \"link\" here is actually a button tag because this is not a navigation event.
12
+ with_different_text:
13
+ data:
14
+ text: "Print this manual"
15
+ with_different_href:
16
+ description: You can specify a alternative `href` URL that will override the default behaviour. When a `href` is specified the print link will render as an anchor tag and be displayed even when JavaScript is disabled.
17
+ data:
18
+ href: "/print"
19
+ with_data_attributes:
20
+ data:
21
+ data_attributes:
22
+ track-category: "printButton"
23
+ track-action: "clicked"
24
+ track-label: "Print this page"
@@ -1,5 +1,6 @@
1
1
  name: Summary list
2
2
  description: Use the summary list to summarise information, for example, a user’s responses at the end of a form.
3
+ body: This component extends the [Summary list component in the Design System](https://design-system.service.gov.uk/components/summary-list/) allowing the rendering of multiple groups of lists, and actions at the group level.
3
4
  accessibility_criteria: |
4
5
  Action links in the component must:
5
6
 
@@ -41,6 +42,32 @@ examples:
41
42
  data_attributes:
42
43
  gtm: "edit-title-summary-body"
43
44
 
45
+ with_delete_on_section:
46
+ data:
47
+ <<: *default-example-data
48
+ delete:
49
+ href: "delete-title-summary-body"
50
+ data_attributes:
51
+ gtm: "delete-title-summary-body"
52
+
53
+ with_edit_and_delete_on_section:
54
+ data:
55
+ <<: *default-example-data
56
+ edit:
57
+ href: "edit-title-summary-body"
58
+ data_attributes:
59
+ gtm: "edit-title-summary-body"
60
+ delete:
61
+ href: "delete-title-summary-body"
62
+ data_attributes:
63
+ gtm: "delete-title-summary-body"
64
+
65
+ with_custom_section_heading:
66
+ data:
67
+ <<: *default-example-data
68
+ heading_level: 2
69
+ heading_size: l
70
+
44
71
  with_custom_link_on_section:
45
72
  description: |
46
73
  Take care that the provided `link_text` still makes sense to screen readers when combined with the title.
@@ -58,6 +58,8 @@ en:
58
58
  policies: "Policies"
59
59
  statistical_data_sets: "Statistical data sets"
60
60
  topical_events: "Topical events"
61
+ print_link:
62
+ text: "Print this page"
61
63
  skip_link:
62
64
  text: "Skip to main content"
63
65
  step_by_step_nav:
@@ -71,3 +73,6 @@ en:
71
73
  email_signup_link_text: "Get email alerts"
72
74
  feed_link_text: "Subscribe to feed"
73
75
  subscriptions: "Subscriptions"
76
+ summary_list:
77
+ edit: "Change"
78
+ delete: "Delete"
@@ -12,9 +12,10 @@ require "govuk_publishing_components/presenters/contextual_navigation"
12
12
  require "govuk_publishing_components/presenters/related_navigation_helper"
13
13
  require "govuk_publishing_components/presenters/step_by_step_nav_helper"
14
14
  require "govuk_publishing_components/presenters/page_with_step_by_step_navigation"
15
- require "govuk_publishing_components/presenters/content_breadcrumbs_based_on_parent"
15
+ require "govuk_publishing_components/presenters/content_breadcrumbs_based_on_ancestors"
16
16
  require "govuk_publishing_components/presenters/content_breadcrumbs_based_on_priority"
17
17
  require "govuk_publishing_components/presenters/content_breadcrumbs_based_on_taxons"
18
+ require "govuk_publishing_components/presenters/content_breadcrumbs_based_on_topic"
18
19
  require "govuk_publishing_components/presenters/checkboxes_helper"
19
20
  require "govuk_publishing_components/presenters/select"
20
21
  require "govuk_publishing_components/presenters/meta_tags"
@@ -1,10 +1,6 @@
1
1
  module GovukPublishingComponents
2
2
  module Presenters
3
3
  class BreadcrumbSelector
4
- def self.call(*args)
5
- new(*args).output
6
- end
7
-
8
4
  attr_reader :content_item, :request, :prioritise_taxon_breadcrumbs
9
5
 
10
6
  def initialize(content_item, request, prioritise_taxon_breadcrumbs)
@@ -13,47 +9,28 @@ module GovukPublishingComponents
13
9
  @prioritise_taxon_breadcrumbs = prioritise_taxon_breadcrumbs
14
10
  end
15
11
 
16
- def content_item_navigation
17
- @content_item_navigation ||= ContextualNavigation.new(content_item, request)
12
+ def breadcrumbs
13
+ best_match_option[:breadcrumbs]
18
14
  end
19
15
 
20
- def parent_item_navigation
21
- @parent_item_navigation ||= ContextualNavigation.new(parent_item, request)
16
+ def step_by_step
17
+ best_match_option[:step_by_step]
22
18
  end
23
19
 
24
- def parent_item
25
- @parent_item ||= Services.content_store.content_item(content_item_navigation.parent_api_path)
26
- rescue GdsApi::ContentStore::ItemNotFound
27
- # Do nothing
28
- end
20
+ def priority_breadcrumbs
21
+ return parent_item_navigation.priority_breadcrumbs if content_item_navigation.html_publication_with_parent?
29
22
 
30
- def parent_item_options
31
- @parent_item_options ||= options(parent_item_navigation)
23
+ content_item_navigation.priority_breadcrumbs
32
24
  end
33
25
 
34
- def content_item_options
35
- @content_item_options ||= options(content_item_navigation)
36
- end
26
+ private
37
27
 
38
- def parent_breadcrumbs
39
- breadcrumbs = [parent_item_options[:breadcrumbs]].flatten # to ensure breadcrumbs always an array
40
- breadcrumbs.last[:is_page_parent] = false
41
- breadcrumbs << {
42
- title: parent_item["title"],
43
- url: parent_item["base_path"],
44
- is_page_parent: true,
45
- }
46
- end
47
-
48
- def output
28
+ def best_match_option
49
29
  return content_item_options unless content_item_navigation.html_publication_with_parent?
50
- return parent_item_options if parent_item_navigation.priority_breadcrumbs
51
-
52
- step_by_step_header = parent_item_options[:step_by_step]
53
30
 
54
31
  {
55
- step_by_step: step_by_step_header,
56
- breadcrumbs: step_by_step_header ? parent_breadcrumbs.first : parent_breadcrumbs,
32
+ step_by_step: parent_is_step_by_step?,
33
+ breadcrumbs: parent_is_step_by_step? ? parent_breadcrumbs.first : parent_breadcrumbs,
57
34
  }
58
35
  end
59
36
 
@@ -61,18 +38,13 @@ module GovukPublishingComponents
61
38
  if navigation.content_tagged_to_a_finder?
62
39
  {
63
40
  step_by_step: false,
64
- breadcrumbs: navigation.breadcrumbs,
41
+ breadcrumbs: navigation.finder_breadcrumbs,
65
42
  }
66
43
  elsif navigation.content_tagged_to_current_step_by_step?
67
44
  {
68
45
  step_by_step: true,
69
46
  breadcrumbs: navigation.step_nav_helper.header,
70
47
  }
71
- elsif navigation.priority_breadcrumbs
72
- {
73
- step_by_step: true,
74
- breadcrumbs: navigation.priority_breadcrumbs,
75
- }
76
48
  elsif navigation.content_is_tagged_to_a_live_taxon? && prioritise_taxon_breadcrumbs
77
49
  {
78
50
  step_by_step: false,
@@ -83,10 +55,10 @@ module GovukPublishingComponents
83
55
  step_by_step: false,
84
56
  breadcrumbs: navigation.breadcrumbs,
85
57
  }
86
- elsif navigation.content_has_curated_related_items?
58
+ elsif navigation.content_has_a_topic?
87
59
  {
88
60
  step_by_step: false,
89
- breadcrumbs: navigation.breadcrumbs,
61
+ breadcrumbs: navigation.topic_breadcrumbs,
90
62
  }
91
63
  elsif navigation.use_taxon_breadcrumbs?
92
64
  {
@@ -102,6 +74,42 @@ module GovukPublishingComponents
102
74
  {}
103
75
  end
104
76
  end
77
+
78
+ def content_item_navigation
79
+ @content_item_navigation ||= ContextualNavigation.new(content_item, request)
80
+ end
81
+
82
+ def parent_item_navigation
83
+ @parent_item_navigation ||= ContextualNavigation.new(parent_item, request)
84
+ end
85
+
86
+ def parent_item
87
+ @parent_item ||= Services.content_store.content_item(content_item_navigation.parent_api_path)
88
+ rescue GdsApi::ContentStore::ItemNotFound
89
+ # Do nothing
90
+ end
91
+
92
+ def parent_item_options
93
+ @parent_item_options ||= options(parent_item_navigation)
94
+ end
95
+
96
+ def content_item_options
97
+ @content_item_options ||= options(content_item_navigation)
98
+ end
99
+
100
+ def parent_breadcrumbs
101
+ breadcrumbs = [parent_item_options[:breadcrumbs]].flatten # to ensure breadcrumbs always an array
102
+ breadcrumbs.last[:is_page_parent] = false
103
+ breadcrumbs << {
104
+ title: parent_item["title"],
105
+ url: parent_item["base_path"],
106
+ is_page_parent: true,
107
+ }
108
+ end
109
+
110
+ def parent_is_step_by_step?
111
+ parent_item_options[:step_by_step]
112
+ end
105
113
  end
106
114
  end
107
115
  end
@@ -0,0 +1,41 @@
1
+ module GovukPublishingComponents
2
+ module Presenters
3
+ # @private
4
+ class ContentBreadcrumbsBasedOnAncestors
5
+ def self.call(content_item)
6
+ new(content_item).breadcrumbs
7
+ end
8
+
9
+ def initialize(content_item)
10
+ @content_item = ContentItem.new(content_item)
11
+ end
12
+
13
+ def breadcrumbs
14
+ ordered_ancestors = all_ancestors.map do |ancestor|
15
+ { title: ancestor.title, url: ancestor.base_path }
16
+ end
17
+
18
+ ordered_ancestors << { title: "Home", url: "/" }
19
+ ordered_ancestors.reverse!
20
+ ordered_ancestors
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :content_item
26
+
27
+ def all_ancestors
28
+ ancestors = []
29
+
30
+ parent = content_item.parent
31
+ while parent
32
+ ancestors << parent
33
+
34
+ parent = parent.parent
35
+ end
36
+
37
+ ancestors
38
+ end
39
+ end
40
+ end
41
+ end
@@ -6,6 +6,7 @@ module GovukPublishingComponents
6
6
  # and the bottom one the lowest priority
7
7
  PRIORITY_TAXONS = {
8
8
  education_coronavirus: "272308f4-05c8-4d0d-abc7-b7c2e3ccd249",
9
+ worker_coronavirus: "b7f57213-4b16-446d-8ded-81955d782680",
9
10
  business_coronavirus: "65666cdf-b177-4d79-9687-b9c32805e450",
10
11
  }.freeze
11
12
 
@@ -2,6 +2,10 @@ module GovukPublishingComponents
2
2
  module Presenters
3
3
  # @private
4
4
  class ContentBreadcrumbsBasedOnTaxons
5
+ def self.call(content_item)
6
+ new(content_item).breadcrumbs
7
+ end
8
+
5
9
  def initialize(content_item)
6
10
  @content_item = ContentItem.new(content_item)
7
11
  end
@@ -0,0 +1,38 @@
1
+ module GovukPublishingComponents
2
+ module Presenters
3
+ class ContentBreadcrumbsBasedOnTopic
4
+ def self.call(content_item)
5
+ new(content_item).breadcrumbs
6
+ end
7
+
8
+ attr_reader :content_item
9
+
10
+ def initialize(content_item)
11
+ @content_item = content_item
12
+ end
13
+
14
+ def breadcrumbs
15
+ breadcrumbs = [{ title: "Home", url: "/" }]
16
+ return breadcrumbs unless topics.present?
17
+
18
+ breadcrumbs << topic_breadcrumb
19
+ breadcrumbs
20
+ end
21
+
22
+ def topic_breadcrumb
23
+ {
24
+ title: first_topic["title"],
25
+ url: first_topic["base_path"],
26
+ }
27
+ end
28
+
29
+ def first_topic
30
+ topics.first
31
+ end
32
+
33
+ def topics
34
+ @topics ||= content_item.dig("links", "topics")
35
+ end
36
+ end
37
+ end
38
+ end
@@ -26,15 +26,22 @@ module GovukPublishingComponents
26
26
  end
27
27
 
28
28
  def taxon_breadcrumbs
29
- @taxon_breadcrumbs ||= ContentBreadcrumbsBasedOnTaxons.new(content_item).breadcrumbs
29
+ @taxon_breadcrumbs ||= ContentBreadcrumbsBasedOnTaxons.call(content_item)
30
30
  end
31
31
 
32
32
  def priority_breadcrumbs
33
33
  @priority_breadcrumbs ||= ContentBreadcrumbsBasedOnPriority.call(content_item)
34
34
  end
35
35
 
36
+ def topic_breadcrumbs
37
+ @topic_breadcrumbs ||= ContentBreadcrumbsBasedOnTopic.call(content_item)
38
+ end
39
+
36
40
  def breadcrumbs
37
- return breadcrumbs_based_on_parent unless content_tagged_to_a_finder?
41
+ breadcrumbs_based_on_ancestors
42
+ end
43
+
44
+ def finder_breadcrumbs
38
45
  return [] unless parent_finder
39
46
 
40
47
  [
@@ -77,6 +84,10 @@ module GovukPublishingComponents
77
84
  content_item["document_type"] == "html_publication"
78
85
  end
79
86
 
87
+ def content_has_a_topic?
88
+ content_item.dig("links", "topics").present?
89
+ end
90
+
80
91
  def tagged_to_brexit?
81
92
  taxons = content_item.dig("links", "taxons").to_a
82
93
  brexit_taxon = "d6c2de5d-ef90-45d1-82d4-5f2438369eea"
@@ -119,8 +130,8 @@ module GovukPublishingComponents
119
130
  step_nav_helper.show_also_part_of_step_nav?
120
131
  end
121
132
 
122
- def breadcrumbs_based_on_parent
123
- ContentBreadcrumbsBasedOnParent.new(content_item).breadcrumbs[:breadcrumbs]
133
+ def breadcrumbs_based_on_ancestors
134
+ ContentBreadcrumbsBasedOnAncestors.call(content_item)
124
135
  end
125
136
 
126
137
  def step_nav_helper
@@ -3,6 +3,8 @@ module GovukPublishingComponents
3
3
  # @private
4
4
  # Only used by the step by step component
5
5
  class PageWithStepByStepNavigation
6
+ MAX_SECTION_LENGTH = RelatedNavigationHelper::MAX_SECTION_LENGTH
7
+
6
8
  def initialize(content_store_response, current_path, query_parameters = {})
7
9
  @content_item = content_store_response.to_h.deep_symbolize_keys
8
10
  @current_path = current_path
@@ -48,7 +50,7 @@ module GovukPublishingComponents
48
50
  end
49
51
 
50
52
  def show_also_part_of_step_nav?
51
- active_step_by_step? && also_part_of_step_nav.any? && step_navs_combined_list.count < 5
53
+ active_step_by_step? && also_part_of_step_nav.any? && step_navs_combined_list.count < MAX_SECTION_LENGTH
52
54
  end
53
55
 
54
56
  def related_links
@@ -31,7 +31,7 @@ module GovukPublishingComponents
31
31
  }
32
32
  when :footer
33
33
  {
34
- "topics" => related_topics,
34
+ "topics" => related_topics_or_taxons,
35
35
  "topical_events" => related_topical_events,
36
36
  "world_locations" => related_world_locations,
37
37
  "statistical_data_sets" => related_statistical_data_sets,
@@ -43,7 +43,7 @@ module GovukPublishingComponents
43
43
  "related_items" => related_items,
44
44
  "related_guides" => related_guides,
45
45
  "collections" => related_document_collections,
46
- "topics" => related_topics,
46
+ "topics" => related_topics_or_taxons,
47
47
  "topical_events" => related_topical_events,
48
48
  "world_locations" => related_world_locations,
49
49
  "statistical_data_sets" => related_statistical_data_sets,
@@ -162,26 +162,27 @@ module GovukPublishingComponents
162
162
  end
163
163
 
164
164
  def related_taxons
165
- content_item_links_for("taxons", only: "taxon")
165
+ @related_taxons ||= content_item_links_for("taxons", only: "taxon")
166
166
  end
167
167
 
168
- def related_topics
169
- if related_legacy_topics.any?
170
- related_legacy_topics
171
- elsif related_taxons.any?
172
- related_taxons
173
- else
174
- []
175
- end
168
+ def related_topics_or_taxons
169
+ return related_topics if related_topics.any?
170
+ return related_taxons if related_taxons.any?
171
+
172
+ []
176
173
  end
177
174
 
178
- def related_legacy_topics
179
- mainstream_browse_page_links = content_item_links_for("mainstream_browse_pages", only: "mainstream_browse_page")
180
- topic_links = content_item_links_for("topics", only: "topic")
175
+ def related_topics
176
+ @related_topics ||= begin
177
+ mainstream_browse_page_links = content_item_links_for("mainstream_browse_pages", only: "mainstream_browse_page")
178
+ topic_links = content_item_links_for("topics", only: "topic")
179
+
180
+ return topic_links if topic_links.present? && mainstream_browse_page_links.empty?
181
181
 
182
- mainstream_browse_page_links + topic_links.find_all do |topic_link|
183
- mainstream_browse_page_links.none? do |mainstream_browse_page_link|
184
- mainstream_browse_page_link[:text] == topic_link[:text]
182
+ mainstream_browse_page_links + topic_links.find_all do |topic_link|
183
+ mainstream_browse_page_links.none? do |mainstream_browse_page_link|
184
+ mainstream_browse_page_link[:text] == topic_link[:text]
185
+ end
185
186
  end
186
187
  end
187
188
  end