ccs-frontend_helpers 0.1.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -0
  3. data/.rubocop.yml +127 -0
  4. data/CHANGELOG.md +44 -0
  5. data/Gemfile +10 -0
  6. data/Gemfile.lock +241 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +102 -0
  9. data/Rakefile +10 -0
  10. data/ccs-frontend_helpers.gemspec +47 -0
  11. data/lib/ccs/frontend_helpers/ccs_frontend/dashboard_panels.rb +79 -0
  12. data/lib/ccs/frontend_helpers/ccs_frontend/footer.rb +141 -0
  13. data/lib/ccs/frontend_helpers/ccs_frontend/header.rb +205 -0
  14. data/lib/ccs/frontend_helpers/ccs_frontend/logo.rb +49 -0
  15. data/lib/ccs/frontend_helpers/ccs_frontend.rb +20 -0
  16. data/lib/ccs/frontend_helpers/govuk_frontend/accordion.rb +115 -0
  17. data/lib/ccs/frontend_helpers/govuk_frontend/back_link.rb +39 -0
  18. data/lib/ccs/frontend_helpers/govuk_frontend/breadcrumbs.rb +76 -0
  19. data/lib/ccs/frontend_helpers/govuk_frontend/button.rb +127 -0
  20. data/lib/ccs/frontend_helpers/govuk_frontend/cookie_banner.rb +136 -0
  21. data/lib/ccs/frontend_helpers/govuk_frontend/details.rb +46 -0
  22. data/lib/ccs/frontend_helpers/govuk_frontend/error_message.rb +67 -0
  23. data/lib/ccs/frontend_helpers/govuk_frontend/error_summary.rb +100 -0
  24. data/lib/ccs/frontend_helpers/govuk_frontend/field/character_count.rb +165 -0
  25. data/lib/ccs/frontend_helpers/govuk_frontend/field/checkboxes.rb +200 -0
  26. data/lib/ccs/frontend_helpers/govuk_frontend/field/date_input.rb +153 -0
  27. data/lib/ccs/frontend_helpers/govuk_frontend/field/file_upload.rb +83 -0
  28. data/lib/ccs/frontend_helpers/govuk_frontend/field/input.rb +153 -0
  29. data/lib/ccs/frontend_helpers/govuk_frontend/field/radios.rb +201 -0
  30. data/lib/ccs/frontend_helpers/govuk_frontend/field/select.rb +124 -0
  31. data/lib/ccs/frontend_helpers/govuk_frontend/field/textarea.rb +106 -0
  32. data/lib/ccs/frontend_helpers/govuk_frontend/field.rb +213 -0
  33. data/lib/ccs/frontend_helpers/govuk_frontend/fieldset.rb +71 -0
  34. data/lib/ccs/frontend_helpers/govuk_frontend/footer.rb +183 -0
  35. data/lib/ccs/frontend_helpers/govuk_frontend/form_group.rb +50 -0
  36. data/lib/ccs/frontend_helpers/govuk_frontend/header.rb +161 -0
  37. data/lib/ccs/frontend_helpers/govuk_frontend/hint.rb +38 -0
  38. data/lib/ccs/frontend_helpers/govuk_frontend/inset_text.rb +44 -0
  39. data/lib/ccs/frontend_helpers/govuk_frontend/label.rb +92 -0
  40. data/lib/ccs/frontend_helpers/govuk_frontend/notification_banner.rb +136 -0
  41. data/lib/ccs/frontend_helpers/govuk_frontend/pagination.rb +336 -0
  42. data/lib/ccs/frontend_helpers/govuk_frontend/panel.rb +51 -0
  43. data/lib/ccs/frontend_helpers/govuk_frontend/phase_banner.rb +49 -0
  44. data/lib/ccs/frontend_helpers/govuk_frontend/skip_link.rb +40 -0
  45. data/lib/ccs/frontend_helpers/govuk_frontend/step_by_step_navigation.rb +215 -0
  46. data/lib/ccs/frontend_helpers/govuk_frontend/summary_list.rb +226 -0
  47. data/lib/ccs/frontend_helpers/govuk_frontend/table.rb +124 -0
  48. data/lib/ccs/frontend_helpers/govuk_frontend/tabs.rb +95 -0
  49. data/lib/ccs/frontend_helpers/govuk_frontend/tag.rb +42 -0
  50. data/lib/ccs/frontend_helpers/govuk_frontend/warning_text.rb +53 -0
  51. data/lib/ccs/frontend_helpers/govuk_frontend.rb +82 -0
  52. data/lib/ccs/frontend_helpers/shared_methods.rb +27 -0
  53. data/lib/ccs/frontend_helpers/version.rb +7 -0
  54. data/lib/ccs/frontend_helpers.rb +20 -0
  55. data/sig/ccs/frontend_helpers.rbs +6 -0
  56. metadata +241 -0
@@ -0,0 +1,215 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+
5
+ require_relative '../shared_methods'
6
+
7
+ module CCS
8
+ module FrontendHelpers
9
+ module GovUKFrontend
10
+ # = GOV.UK Step by step navigation
11
+ #
12
+ # This helper is used for generating the Step by step navigation component from the
13
+ # {https://design-system.service.gov.uk/patterns/step-by-step-navigation/ GDS - Pages - Step by step navigation}
14
+ #
15
+ # To use this component you need the following from {https://github.com/alphagov/govuk_publishing_components GOV.UK Publishing Components}.
16
+ # For the SCSS components you should add:
17
+ # - {https://github.com/alphagov/govuk_publishing_components/blob/main/app/assets/stylesheets/govuk_publishing_components/components/_step-by-step-nav.scss _step-by-step-nav.scss}
18
+ # - {https://github.com/alphagov/govuk_publishing_components/blob/main/app/assets/stylesheets/govuk_publishing_components/components/_step-by-step-nav-related.scss _step-by-step-nav-related.scss}
19
+ # - {https://github.com/alphagov/govuk_publishing_components/blob/main/app/assets/stylesheets/govuk_publishing_components/components/_step-by-step-nav-header.scss _step-by-step-nav-header.scss}
20
+ # For the JavaScript you should add:
21
+ # - {https://github.com/alphagov/govuk_publishing_components/blob/main/app/assets/javascripts/govuk_publishing_components/components/step-by-step-nav.js step-by-step-nav.js}
22
+
23
+ module StepByStepNavigation
24
+ include SharedMethods
25
+ include ActionView::Helpers
26
+ include ActionView::Context
27
+
28
+ # Generates the HTML for the GOV.UK Step by step navigation component (experimental)
29
+ #
30
+ # @param step_by_step_sections [Array] the navigation items that will be rendered to the page.
31
+ # See {govuk_step_by_step_navigation_section} for more details
32
+ # @param govuk_step_by_step_navigation_options [Hash] options that will be used in customising the HTML
33
+ #
34
+ # @option govuk_step_by_step_navigation_options [String] :classes additional CSS classes for the step by step navigation HTML
35
+ # @option govuk_step_by_step_navigation_options [Hash] :attributes ({data: { module: 'govuk-step-by-step-navigation', 'show-text': 'Show', 'hide-text': 'Hide', 'show-all-text': 'Show all', 'hide-all-text': 'Hide all' } })
36
+ # any additional attributes that will added as part of the HTML
37
+ #
38
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Step by step navigation
39
+ # which can then be rendered on the page
40
+
41
+ def govuk_step_by_step_navigation(step_by_step_sections, **govuk_step_by_step_navigation_options)
42
+ initialise_attributes_and_set_classes(govuk_step_by_step_navigation_options, 'gem-c-step-nav gem-c-step-nav--large gem-c-step-nav--active')
43
+ determine_step_by_step_navigation_attributes(govuk_step_by_step_navigation_options)
44
+
45
+ tag.div(**govuk_step_by_step_navigation_options[:attributes]) do
46
+ tag.ol(class: 'gem-c-step-nav__steps') do
47
+ step_by_step_sections.each.with_index(1) { |step_by_step_section, section_index| concat(govuk_step_by_step_navigation_section(step_by_step_section, section_index.to_s)) }
48
+ end
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ # The HTML for a section within GOV.UK Step by step navigation, used by {govuk_step_by_step_navigation}
55
+ #
56
+ # @param step_by_step_section [Hash] the parameters that will be used to create the section
57
+ # @param section_index [String] the index of the section
58
+ #
59
+ # @option step_by_step_section [Hash] :heading the paramaters for the section heading,
60
+ # see {govuk_step_by_step_navigation_heading} for more details
61
+ # @option step_by_step_section [Array] :content the paramaters for the section content,
62
+ # see {govuk_step_by_step_navigation_content} for more details
63
+ #
64
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Step by step navigation section
65
+ # which is used in {govuk_step_by_step_navigation}
66
+
67
+ def govuk_step_by_step_navigation_section(step_by_step_section, section_index)
68
+ section_id = convert_to_id(step_by_step_section[:heading][:text])
69
+
70
+ tag.li(class: 'gem-c-step-nav__step js-step', id: section_id) do
71
+ concat(govuk_step_by_step_navigation_heading(step_by_step_section[:heading], section_index))
72
+ concat(govuk_step_by_step_navigation_content(step_by_step_section[:content], section_id, section_index))
73
+ end
74
+ end
75
+
76
+ # The HTML for a section heading within GOV.UK Step by step navigation, used by {govuk_step_by_step_navigation_section}
77
+ #
78
+ # @param section_heading [Hash] the parameters that will be used to create the heading
79
+ # @param section_index [String] the index of the section
80
+ #
81
+ # @option section_heading [Hash] :text text for the section heading
82
+ # @option section_heading [Hash] :logic (nil) text to show instead of a number in the sidebar
83
+ #
84
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Step by step navigation section heading
85
+ # which is used in {govuk_step_by_step_navigation_section}
86
+
87
+ def govuk_step_by_step_navigation_heading(section_heading, section_index)
88
+ logic = section_heading[:logic]
89
+
90
+ tag.div(class: 'gem-c-step-nav__header js-toggle-panel', data: { position: section_index }) do
91
+ tag.h2(class: 'gem-c-step-nav__title') do
92
+ concat(tag.span(class: "gem-c-step-nav__circle gem-c-step-nav__circle--#{logic ? 'logic' : 'number'}") do
93
+ tag.span(class: 'gem-c-step-nav__circle-inner') do
94
+ tag.span(class: 'gem-c-step-nav__circle-background') do
95
+ concat(tag.span('Step', class: 'govuk-visually-hidden'))
96
+ concat(logic || section_index)
97
+ end
98
+ end
99
+ end)
100
+ concat(tag.span(class: 'js-step-title') do
101
+ tag.span(section_heading[:text], class: 'js-step-title-text')
102
+ end)
103
+ end
104
+ end
105
+ end
106
+
107
+ # The HTML for a section content within GOV.UK Step by step navigation, used by {govuk_step_by_step_navigation_section}
108
+ #
109
+ # @param content [Array] an array of the content items that will be rendered within the section.
110
+ # Only two types of content are allowed:
111
+ # - +:paragraph+ - see {govuk_step_by_step_navigation_paragraph}
112
+ # - +:list+ - see {govuk_step_by_step_navigation_list}
113
+ # @param section_id [String] the id of the section
114
+ # @param section_index [String] the index of the section
115
+ #
116
+ # @option content [Symbol] :type the type of content, either +:paragraph+ or +list+
117
+ # @option content [Symbol] :text the text for the paragraph. Ignored unless the +type+ is +:list+
118
+ # @option content [Symbol] :items the items for the list. Ignored unless the +type+ is +:paragraph+
119
+ #
120
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Step by step navigation section content
121
+ # which is used in {govuk_step_by_step_navigation_section}
122
+
123
+ def govuk_step_by_step_navigation_content(content, section_id, section_index)
124
+ tag.div(class: 'gem-c-step-nav__panel js-panel', id: "step-panel-#{section_id}-#{section_index}") do
125
+ content.each do |element|
126
+ concat(
127
+ case element[:type]
128
+ when :paragraph
129
+ govuk_step_by_step_navigation_paragraph(element[:text])
130
+ when :list
131
+ govuk_step_by_step_navigation_list(element[:items])
132
+ end
133
+ )
134
+ end
135
+ end
136
+ end
137
+
138
+ # The HTML for the paragraph item within the GOV.UK Step by step navigation content, used by {govuk_step_by_step_navigation_content}
139
+ #
140
+ # @param text [String] the text for the paragraph
141
+ #
142
+ # @return [ActiveSupport::SafeBuffer] the HTML for the paragraph
143
+ # which is used in {govuk_step_by_step_navigation_content}
144
+
145
+ def govuk_step_by_step_navigation_paragraph(text)
146
+ tag.p(
147
+ text,
148
+ class: 'gem-c-step-nav__paragraph',
149
+ )
150
+ end
151
+
152
+ # The HTML for the list items within the GOV.UK Step by step navigation content, used by {govuk_step_by_step_navigation_content}
153
+ #
154
+ # @param items [Array] an array of the list items,
155
+ # see {govuk_step_by_step_navigation_list_item} for more details
156
+ #
157
+ # @return [ActiveSupport::SafeBuffer] the HTML for the list
158
+ # which is used in {govuk_step_by_step_navigation_content}
159
+
160
+ def govuk_step_by_step_navigation_list(items)
161
+ tag.ul(class: 'gem-c-step-nav__list gem-c-step-nav__list--choice', data: { length: items.length.to_s }) do
162
+ items.each do |item|
163
+ concat(govuk_step_by_step_navigation_list_item(item[:text], item[:no_marker]))
164
+ end
165
+ end
166
+ end
167
+
168
+ # The HTML for a list item, used by {govuk_step_by_step_navigation_list}
169
+ #
170
+ # @param text [Symbol] the text of the list item
171
+ # @param no_marker [Symbol] (nil) switch to hide the bullet marker
172
+ #
173
+ # @return [ActiveSupport::SafeBuffer] the HTML for the list item
174
+ # which is used in {govuk_step_by_step_navigation_list}
175
+
176
+ def govuk_step_by_step_navigation_list_item(text, no_marker)
177
+ list_item_classes = ['gem-c-step-nav__list-item js-list-item']
178
+ list_item_classes << 'gem-c-step-nav__list--no-marker' if no_marker
179
+
180
+ tag.li(class: list_item_classes) do
181
+ tag.span(text)
182
+ end
183
+ end
184
+
185
+ # Converts the title text into a string to be used as the section id
186
+ #
187
+ # @param title [String] the section title that will be converted
188
+ #
189
+ # @return [String] the section id
190
+
191
+ def convert_to_id(title)
192
+ title.downcase.gsub(' ', '-').gsub('(', '').gsub(')', '')
193
+ end
194
+
195
+ # Generates a hash with the attributes used in {govuk_step_by_step_navigation}
196
+ #
197
+ # @param govuk_step_by_step_navigation_options [Hash] options that will be used in customising the HTML
198
+ #
199
+ # @option (see govuk_step_by_step_navigation)
200
+ #
201
+ # @return [Hash] contains the HTMl attributes used in {govuk_step_by_step_navigation}
202
+
203
+ def determine_step_by_step_navigation_attributes(govuk_step_by_step_navigation_options)
204
+ set_data_module(govuk_step_by_step_navigation_options, 'govuk-step-by-step-navigation')
205
+
206
+ DEFAULT_SHOW_HIDE_TEXT.each { |key, value| govuk_step_by_step_navigation_options[:attributes][:data][key] ||= value }
207
+ end
208
+
209
+ # Default text for the show and hide buttons which are part of each section
210
+
211
+ DEFAULT_SHOW_HIDE_TEXT = { 'show-text': 'Show', 'hide-text': 'Hide', 'show-all-text': 'Show all', 'hide-all-text': 'Hide all' }.freeze
212
+ end
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,226 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+
5
+ require_relative '../shared_methods'
6
+
7
+ module CCS
8
+ module FrontendHelpers
9
+ module GovUKFrontend
10
+ # = GOV.UK Summary list
11
+ #
12
+ # This helper is used for generating the summary list component from the
13
+ # {https://design-system.service.gov.uk/components/summary-list GDS - Components - Summary list}
14
+
15
+ module SummaryList
16
+ include SharedMethods
17
+ include ActionView::Context
18
+ include ActionView::Helpers::TagHelper
19
+ include ActionView::Helpers::TextHelper
20
+ include ActionView::Helpers::UrlHelper
21
+
22
+ # Generates the HTML for the GOV.UK Summary list component
23
+ #
24
+ # @param summary_list_items [Array] the list of summary items. See {govuk_summary_list_row}
25
+ # @param govuk_summary_list_options [Hash] options that will be used in customising the HTML
26
+ #
27
+ # @option govuk_summary_list_options [String] :classes additional CSS classes for the summary list HTML
28
+ # @option govuk_summary_list_options [Hash] :attributes ({}) any additional attributes that will be added as part of the HTML
29
+ #
30
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Summary list
31
+ # which can then be rendered on the page
32
+
33
+ def govuk_summary_list(summary_list_items, **govuk_summary_list_options)
34
+ if govuk_summary_list_options[:card]
35
+ govuk_summary_card(**govuk_summary_list_options[:card]) do
36
+ _govuk_summary_list(summary_list_items, govuk_summary_list_options)
37
+ end
38
+ else
39
+ _govuk_summary_list(summary_list_items, govuk_summary_list_options)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ # Generates the HTML for the GOV.UK Summary list.
46
+ # Used in {govuk_summary_list} to gererate the actual summary list.
47
+ #
48
+ # @param (see govuk_summary_list)
49
+ #
50
+ # @option (see govuk_summary_list)
51
+ #
52
+ # @return (see govuk_summary_list)
53
+
54
+ def _govuk_summary_list(summary_list_items, govuk_summary_list_options)
55
+ initialise_attributes_and_set_classes(govuk_summary_list_options, 'govuk-summary-list')
56
+
57
+ any_row_has_actions = summary_list_items.any? { |summary_list_item| summary_list_item.dig(:actions, :items).present? }
58
+
59
+ tag.dl(**govuk_summary_list_options[:attributes]) do
60
+ summary_list_items.each do |summary_list_item|
61
+ concat(govuk_summary_list_row(summary_list_item, any_row_has_actions))
62
+ end
63
+ end
64
+ end
65
+
66
+ # rubocop:disable Metrics/AbcSize
67
+
68
+ # Generates the HTML for a summary list row used in {govuk_summary_list}
69
+ #
70
+ # @param summary_list_item [Hash] the list of summary items
71
+ # @param any_row_has_actions [Boolean] flag to indicate if any rows have actioms
72
+ #
73
+ # @option summary_list_item [String] :classes additional CSS classes for the summary row HTML
74
+ # @option summary_list_item [Hash] :key the key for the summary list.
75
+ # Has the following options:
76
+ # - +:text+ - the text for the key
77
+ # - +:classes+ - additional classes for the key
78
+ # @option summary_list_item [Hash] :value the value for the summary list.
79
+ # Has the following options:
80
+ # - +:text+ - the text for the value
81
+ # - +:classes+ - additional classes for the value
82
+ # @option summary_list_item [Hash] :actions the actions for the summary list.
83
+ # Has the following options:
84
+ # - +:items+ - the action items (see {govuk_summary_list_action_link})
85
+ # - +:classes+ - additional classes for the actions
86
+ #
87
+ # @return [ActiveSupport::SafeBuffer] the HTML for a summary list row
88
+ # used in {govuk_summary_list}
89
+
90
+ def govuk_summary_list_row(summary_list_item, any_row_has_actions)
91
+ item_has_actions = summary_list_item.dig(:actions, :items).present?
92
+ summary_list_item_classes = "govuk-summary-list__row #{'govuk-summary-list__row--no-actions' if any_row_has_actions && !item_has_actions}".rstrip
93
+ summary_list_item_classes += " #{summary_list_item[:classes]}".rstrip
94
+
95
+ tag.div(class: summary_list_item_classes) do
96
+ concat(tag.dt(summary_list_item[:key][:text], class: govuk_summary_list_cell_classes(:key, summary_list_item)))
97
+ concat(tag.dd(summary_list_item[:value][:text], class: govuk_summary_list_cell_classes(:value, summary_list_item)))
98
+ concat(tag.dd(govuk_summary_list_actions(summary_list_item[:actions]), class: govuk_summary_list_cell_classes(:actions, summary_list_item))) if item_has_actions
99
+ end
100
+ end
101
+
102
+ # rubocop:enable Metrics/AbcSize
103
+
104
+ # Generates the HTML for a summary list actions used in {govuk_summary_list_row}
105
+ #
106
+ # @param summary_list_actions [Hash] the actions for the summary list
107
+ #
108
+ # @option summary_list_actions [Hash] :items the action items (see {govuk_summary_list_action_link})
109
+ # @option summary_list_actions [String] :classes additional CSS classes for the summary row HTML
110
+ #
111
+ # @return [ActiveSupport::SafeBuffer] the HTML for the summary list actions
112
+ # used in {govuk_summary_list_row}
113
+
114
+ def govuk_summary_list_actions(summary_list_actions)
115
+ if summary_list_actions[:items].length == 1
116
+ govuk_summary_list_action_link(summary_list_actions[:items].first)
117
+ else
118
+ tag.ul(class: 'govuk-summary-list__actions-list') do
119
+ summary_list_actions[:items].each do |summary_list_actions_item|
120
+ concat(tag.li(govuk_summary_list_action_link(summary_list_actions_item), class: 'govuk-summary-list__actions-list-item'))
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ # Generates the HTML for a summary list action link used in {govuk_summary_list_actions}
127
+ #
128
+ # @param summary_list_action_item [Hash] an individual action ite,
129
+ #
130
+ # @option summary_list_action_item [String] :text text for the link
131
+ # @option summary_list_action_item [String] :href href for the link
132
+ # @option summary_list_action_item [String] :classes additional CSS classes for the summary link HTML
133
+ # @option summary_list_action_item [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
134
+ #
135
+ # @return [ActiveSupport::SafeBuffer] the HTML for the summary list action link
136
+ # used in {govuk_summary_list_row}
137
+
138
+ def govuk_summary_list_action_link(summary_list_action_item)
139
+ initialise_attributes_and_set_classes(summary_list_action_item, 'govuk-link')
140
+
141
+ link_to(summary_list_action_item[:href], **summary_list_action_item[:attributes]) do
142
+ concat(summary_list_action_item[:text])
143
+ concat(tag.span(summary_list_action_item[:visually_hidden_text], class: 'govuk-visually-hidden')) if summary_list_action_item[:visually_hidden_text]
144
+ end
145
+ end
146
+
147
+ # rubocop:disable Metrics/AbcSize
148
+
149
+ # Creates the wrapper for the govuk summary card used in {govuk_summary_list}
150
+ #
151
+ # @param govuk_summary_card_options [Hash] options for the summary card
152
+ #
153
+ # @option govuk_summary_card_options [Hash] :title options for the title section of the card header
154
+ # @option govuk_summary_card_options [Hash] :actions options for the summary card actions section (see {govuk_summary_card_actions})
155
+ # @option govuk_summary_card_options [String] :classes additional CSS classes for the summary card HTML
156
+ # @option govuk_summary_card_options [Hash] :attributes ({}) any additional attributes that will be added as part of the HTML
157
+ #
158
+ # @option title [String] :text the title of the card
159
+ # @option title [String] :heading_level (2) heading level, from 1 to 6
160
+ # @option title [String] :classes additional classes to add to the title wrapper
161
+ #
162
+ # @yield HTML for the summary list (see {_govuk_summary_list})
163
+ #
164
+ # @return [ActiveSupport::SafeBuffer] the HTML for the summary card that
165
+ # wraps round {_govuk_summary_list} and
166
+ # used in {govuk_summary_list}
167
+
168
+ def govuk_summary_card(**govuk_summary_card_options, &block)
169
+ initialise_attributes_and_set_classes(govuk_summary_card_options, 'govuk-summary-card')
170
+
171
+ tag.div(**govuk_summary_card_options[:attributes]) do
172
+ concat(tag.div(class: 'govuk-summary-card__title-wrapper') do
173
+ if govuk_summary_card_options[:title]
174
+ govuk_summary_card_options[:title][:heading_level] ||= 2
175
+
176
+ concat(tag.send(:"h#{govuk_summary_card_options[:title][:heading_level]}", govuk_summary_card_options[:title][:text], class: "govuk-summary-card__title #{govuk_summary_card_options[:title][:classes]}".rstrip))
177
+ end
178
+ concat(govuk_summary_card_actions(govuk_summary_card_options[:actions])) if govuk_summary_card_options[:actions]
179
+ end)
180
+ concat(tag.div(class: 'govuk-summary-card__content', &block))
181
+ end
182
+ end
183
+
184
+ # rubocop:enable Metrics/AbcSize
185
+
186
+ # Generates the HTML for a summary card actions used in {govuk_summary_card}
187
+ #
188
+ # @param actions [Hash] options for the summary card actions
189
+ #
190
+ # @option actions [String] :classes additional CSS classes for the summary card actions HTML
191
+ # @option actions [Array] :items the action item objects which are passed to {govuk_summary_list_action_link}
192
+ #
193
+ # @return [ActiveSupport::SafeBuffer] the HTML for the summary card actions
194
+ # used in {govuk_summary_card}
195
+
196
+ def govuk_summary_card_actions(actions)
197
+ action_classes = "govuk-summary-card__actions #{actions[:classes]}".rstrip
198
+
199
+ if actions[:items].length == 1
200
+ tag.div(class: action_classes) do
201
+ govuk_summary_list_action_link(actions[:items][0])
202
+ end
203
+ else
204
+ tag.ul(class: action_classes) do
205
+ actions[:items].each { |action_item| concat(tag.li(govuk_summary_list_action_link(action_item), class: 'govuk-summary-card__action')) }
206
+ end
207
+ end
208
+ end
209
+
210
+ # Generates a string containing the classes for the cell used in {govuk_summary_list_row}
211
+ #
212
+ # @param type [String] the type of the row. One of:
213
+ # - +'key'+
214
+ # - +'value'+
215
+ # - +'actions'+
216
+ # @param summary_list_item [Hash] see {govuk_summary_list_row}
217
+ #
218
+ # @return [String] the classes for a summary list cell
219
+
220
+ def govuk_summary_list_cell_classes(type, summary_list_item)
221
+ "govuk-summary-list__#{type} #{summary_list_item[type][:classes]}".rstrip
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+
5
+ require_relative '../shared_methods'
6
+
7
+ module CCS
8
+ module FrontendHelpers
9
+ module GovUKFrontend
10
+ # = GOV.UK Table
11
+ #
12
+ # This helper is used for generating the table component from the
13
+ # {https://design-system.service.gov.uk/components/table GDS - Components - Table}
14
+
15
+ module Table
16
+ include SharedMethods
17
+ include ActionView::Context
18
+ include ActionView::Helpers::TagHelper
19
+ include ActionView::Helpers::TextHelper
20
+
21
+ # Generates the HTML for the GOV.UK Table component
22
+ #
23
+ # @param rows [Array] array of table rows and cells. See {govuk_table_row}
24
+ # @param head [NilClass,Array] array of table head cells. See {govuk_table_head}
25
+ # @param govuk_table_options [Hash] options that will be used in customising the HTML
26
+ #
27
+ # @option govuk_table_options [String] :classes additional CSS classes for the table HTML
28
+ # @option govuk_table_options [String] :first_cell_is_header if set to true, first cell in table row will be a TH instead of a TD
29
+ # @option govuk_table_options [Hash] :caption options for a table caption. See {govuk_table_caption}
30
+ # @option govuk_table_options [Hash] :attributes ({}) any additional attributes that will be added as part of the HTML
31
+ #
32
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Table
33
+ # which can then be rendered on the page
34
+
35
+ def govuk_table(rows, head = nil, **govuk_table_options)
36
+ initialise_attributes_and_set_classes(govuk_table_options, 'govuk-table')
37
+
38
+ tag.table(**govuk_table_options[:attributes]) do
39
+ concat(govuk_table_caption(govuk_table_options[:caption])) if govuk_table_options[:caption]
40
+ concat(govuk_table_head(head)) if head
41
+ concat(tag.tbody(class: 'govuk-table__body') do
42
+ rows.each { |row| concat(govuk_table_row(row, govuk_table_options[:first_cell_is_header])) }
43
+ end)
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # Generates the HTML for the the table caption used in {govuk_table}
50
+ #
51
+ # @param caption [Hash] options that are used to define the caption
52
+ #
53
+ # @option caption [String] :text the caption text
54
+ # @option caption [String] :classes additional CSS classes for the table caption
55
+ #
56
+ # @return [ActiveSupport::SafeBuffer] the HTML for the table caption used in {govuk_table}
57
+
58
+ def govuk_table_caption(caption)
59
+ tag.caption(caption[:text], class: "govuk-table__caption #{caption[:classes]}".rstrip)
60
+ end
61
+
62
+ # Generates the HTML for the table head used in {govuk_table}
63
+ #
64
+ # @param head [Array] an array of table head cells
65
+ #
66
+ # @option head [String] :text the text of the cell
67
+ # @option head [String] :classes additional CSS classes for the cell
68
+ # @option head [String] :format specify format of a cell
69
+ # @option head [Hash] :attributes ({}) any additional attributes that will be added as part of the cell
70
+ #
71
+ # @return [ActiveSupport::SafeBuffer] the HTML for the table head used in {govuk_table}
72
+
73
+ def govuk_table_head(head)
74
+ tag.thead(class: 'govuk-table__head') do
75
+ tag.tr(class: 'govuk-table__row') do
76
+ head.each do |cell|
77
+ initialise_attributes_and_set_classes(cell, 'govuk-table__header')
78
+
79
+ cell[:attributes][:class] += " govuk-table__header--#{cell[:format]}" if cell[:format]
80
+ cell[:attributes][:scope] = 'col'
81
+
82
+ concat(tag.th(cell[:text], **cell[:attributes]))
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ # Generates the HTML for a table row used in {govuk_table}
89
+ #
90
+ # @param row [Array] an array of a rows cells
91
+ # @param first_cell_is_header [Boolean] if set to true, first cell in the row will be a TH instead of a TD
92
+ #
93
+ # @option row [String] :text the text of the cell
94
+ # @option row [String] :classes additional CSS classes for the cell
95
+ # @option row [String] :format specify format of a cell
96
+ # @option row [Hash] :attributes ({}) any additional attributes that will be added as part of the cell
97
+ #
98
+ # @return [ActiveSupport::SafeBuffer] the HTML for a table row used in {govuk_table}
99
+
100
+ def govuk_table_row(row, first_cell_is_header)
101
+ tag.tr(class: 'govuk-table__row') do
102
+ row.each.with_index do |cell, index|
103
+ tag_type = if first_cell_is_header && index.zero?
104
+ initialise_attributes_and_set_classes(cell, 'govuk-table__header')
105
+
106
+ cell[:attributes][:scope] = 'row'
107
+
108
+ :th
109
+ else
110
+ initialise_attributes_and_set_classes(cell, 'govuk-table__cell')
111
+
112
+ cell[:attributes][:class] += " govuk-table__cell--#{cell[:format]}" if cell[:format]
113
+
114
+ :td
115
+ end
116
+
117
+ concat(tag.send(tag_type, cell[:text], **cell[:attributes]))
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+
5
+ require_relative '../shared_methods'
6
+
7
+ module CCS
8
+ module FrontendHelpers
9
+ module GovUKFrontend
10
+ # = GOV.UK Tabs
11
+ #
12
+ # This helper is used for generating the tabs component from the
13
+ # {https://design-system.service.gov.uk/components/tabs GDS - Components - Tabs}
14
+
15
+ module Tabs
16
+ include SharedMethods
17
+ include ActionView::Context
18
+ include ActionView::Helpers::FormTagHelper
19
+ include ActionView::Helpers::TagHelper
20
+ include ActionView::Helpers::TextHelper
21
+ include ActionView::Helpers::UrlHelper
22
+
23
+ # Generates the HTML for the GOV.UK Tabs component
24
+ #
25
+ # @param items [Array] array of tab items. See {govuk_tabs_list_item}
26
+ # @param title [NilClass,String] title for the tabs table of contents
27
+ # @param govuk_tabs_options [Hash] options that will be used in customising the HTML
28
+ #
29
+ # @option govuk_tabs_options [String] :classes additional CSS classes for the tabs HTML
30
+ # @option govuk_tabs_options [String] :id_prefix prefix id for each tab item if no id is specified on each item
31
+ # @option govuk_tabs_options [Hash] :attributes ({}) any additional attributes that will be added as part of the HTML
32
+ #
33
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Tabs
34
+ # which can then be rendered on the page
35
+
36
+ def govuk_tabs(items, title = 'Contents', **govuk_tabs_options)
37
+ initialise_attributes_and_set_classes(govuk_tabs_options, 'govuk-tabs')
38
+ set_data_module(govuk_tabs_options, 'govuk-tabs')
39
+
40
+ id_prefix = govuk_tabs_options[:id_prefix] || sanitize_to_id(title.downcase)
41
+
42
+ tag.div(**govuk_tabs_options[:attributes]) do
43
+ concat(tag.h2(title, class: 'govuk-tabs__title'))
44
+ concat(tag.ul(class: 'govuk-tabs__lis') do
45
+ items.each.with_index(1) { |list_item, index| concat(govuk_tabs_list_item(list_item, index, id_prefix)) }
46
+ end)
47
+ items.each.with_index(1) { |panel_item, index| concat(govuk_tabs_panel_item(panel_item[:panel], index)) }
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ # Generates the HTML for a tab list item used in {govuk_tabs}
54
+ #
55
+ # @param list_item [Hash] options used to form the tab
56
+ # @param index [Integer] the index of the tab
57
+ # @param id_prefix [String] prefix id for a tab item if no id is specified
58
+ #
59
+ # @option list_item [String] :label the text label of a tab item
60
+ # @option list_item [Hash] :panel content for panel. See {govuk_tabs_panel_item}
61
+ # @option list_item [Hash] :attributes ({}) any additional attributes that will be added as part of the tab link HTML
62
+ #
63
+ # @return [ActiveSupport::SafeBuffer] the HTML for a tab list item used in {govuk_tabs}
64
+
65
+ def govuk_tabs_list_item(list_item, index, id_prefix)
66
+ (list_item[:attributes] ||= {})[:class] = 'govuk-tabs__tab'
67
+ (list_item[:panel][:attributes] ||= {})[:id] ||= "#{id_prefix}-#{index}"
68
+
69
+ tag.li(class: "govuk-tabs__list-item #{'govuk-tabs__list-item--selected' if index == 1}".rstrip) do
70
+ link_to(list_item[:label], "##{list_item[:panel][:attributes][:id]}", **list_item[:attributes])
71
+ end
72
+ end
73
+
74
+ # Generates the HTML for a tab panel used in {govuk_tabs}
75
+ #
76
+ # @param panel_item [Hash] options used to form the tab panel
77
+ # @param index [Integer] the index of the tab
78
+ #
79
+ # @option panel_item [ActiveSupport::SafeBuffer] :content HTML to use within the each tab panel
80
+ # @option panel_item [String] :text if +:content+ is blank then this is the text within the panel
81
+ # @option panel_item [Hash] :attributes ({}) any additional attributes that will be added as part of the tab panel HTML
82
+ #
83
+ # @return [ActiveSupport::SafeBuffer] the HTML for a tab panel used in {govuk_tabs}
84
+
85
+ def govuk_tabs_panel_item(panel_item, index)
86
+ panel_item[:attributes][:class] = "govuk-tabs__panel #{'govuk-tabs__panel--hidden' if index > 1}".rstrip
87
+
88
+ tag.div(**panel_item[:attributes]) do
89
+ panel_item[:content] || tag.p(panel_item[:text], class: 'govuk-body')
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end