govuk_publishing_components 21.55.4 → 21.57.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.
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