crown_marketplace_utils 0.1.0.beta.1 → 0.1.0.beta.3

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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +14 -0
  4. data/Gemfile +0 -4
  5. data/Gemfile.lock +45 -29
  6. data/README.md +44 -1
  7. data/crown_marketplace_utils.gemspec +11 -8
  8. data/lib/crown_marketplace_utils/gov_uk_helper/breadcrumbs.rb +76 -0
  9. data/lib/crown_marketplace_utils/gov_uk_helper/button.rb +130 -0
  10. data/lib/crown_marketplace_utils/gov_uk_helper/details.rb +14 -8
  11. data/lib/crown_marketplace_utils/gov_uk_helper/error_message.rb +18 -11
  12. data/lib/crown_marketplace_utils/gov_uk_helper/field/character_count.rb +193 -0
  13. data/lib/crown_marketplace_utils/gov_uk_helper/field/checkboxes.rb +209 -0
  14. data/lib/crown_marketplace_utils/gov_uk_helper/field/input.rb +160 -0
  15. data/lib/crown_marketplace_utils/gov_uk_helper/field/radios.rb +205 -0
  16. data/lib/crown_marketplace_utils/gov_uk_helper/field/select.rb +166 -0
  17. data/lib/crown_marketplace_utils/gov_uk_helper/field/textarea.rb +127 -0
  18. data/lib/crown_marketplace_utils/gov_uk_helper/field.rb +263 -0
  19. data/lib/crown_marketplace_utils/gov_uk_helper/fieldset.rb +75 -0
  20. data/lib/crown_marketplace_utils/gov_uk_helper/form_group.rb +60 -0
  21. data/lib/crown_marketplace_utils/gov_uk_helper/header.rb +172 -0
  22. data/lib/crown_marketplace_utils/gov_uk_helper/hint.rb +12 -6
  23. data/lib/crown_marketplace_utils/gov_uk_helper/label.rb +97 -0
  24. data/lib/crown_marketplace_utils/gov_uk_helper/notification_banner.rb +139 -0
  25. data/lib/crown_marketplace_utils/gov_uk_helper/pagination.rb +214 -0
  26. data/lib/crown_marketplace_utils/gov_uk_helper/step_by_step_navigation.rb +225 -0
  27. data/lib/crown_marketplace_utils/gov_uk_helper/tag.rb +39 -0
  28. data/lib/crown_marketplace_utils/gov_uk_helper.rb +37 -2
  29. data/lib/crown_marketplace_utils/version.rb +1 -1
  30. data/lib/crown_marketplace_utils.rb +6 -1
  31. metadata +75 -31
  32. data/lib/crown_marketplace_utils/engine.rb +0 -11
@@ -0,0 +1,263 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'fieldset'
4
+ require_relative 'form_group'
5
+ require_relative 'hint'
6
+ require_relative 'label'
7
+
8
+ module CrownMarketplaceUtils
9
+ module GovUkHelper
10
+ # = GOV.UK Field
11
+ #
12
+ # This module contains methods to wrap the:
13
+ # - fieldset
14
+ # - form group
15
+ # - label
16
+ # - hint
17
+ # - error message
18
+ # around some kind of input.
19
+ #
20
+ # The wrapper functions in this module are used
21
+ # to create the fields using the structure of a GDS input field component.
22
+
23
+ module Field
24
+ include Fieldset
25
+ include FormGroup
26
+ include Hint
27
+ include Label
28
+
29
+ # Generates the HTML to wrap arround a GDS input field component.
30
+ #
31
+ # @param type [Symbol] the type of the field
32
+ # @param attribute [String, Symbol] the attribute of the field
33
+ # @param error_message [String] the error message to be displayed
34
+ # @param govuk_field_options [Hash] options that will be used for the parts of the form group, label, hint and field
35
+ #
36
+ # @option govuk_field_options [Hash] :form_group_options ({}) the options for govuk_form_group {govuk_form_group}
37
+ # @option govuk_field_options [Hash] :label the parameters that will be used to create the label for the field:
38
+ # - +:text+ (required) - the label text
39
+ # - +:options+ - default: { } - the options for govuk_label {govuk_label}
40
+ # @option govuk_field_options [Hash] :hint (nil) the parameters that will be used to create the hint for the field
41
+ # - +:text+ (required) - the hint text
42
+ # - +:options+ - default: { } - the options for govuk_hint {govuk_hint}
43
+ # If no hint is given then no hint will be rendered
44
+ # @option govuk_field_options [Hash] :field_options ({}) the options that will be used when rendering the field.
45
+ # For more details look at a module that uses +Field+.
46
+ #
47
+ # @yield the field HTML
48
+ #
49
+ # @yieldparam govuk_field_options [Hash] the HTML options used when rendering the field
50
+ #
51
+ # @return [ActiveSupport::SafeBuffer] the HTML that wraps arround the field
52
+
53
+ def govuk_field(type, attribute, error_message = nil, **govuk_field_options)
54
+ field_key = :"#{type}_options"
55
+
56
+ set_label_for_if_custom_id(field_key, govuk_field_options)
57
+ set_hint_id(attribute, govuk_field_options)
58
+
59
+ govuk_form_group(attribute, error_message, **(govuk_field_options[:form_group_options] || {})) do |display_error_message|
60
+ set_field_described_by(field_key, attribute, error_message, govuk_field_options)
61
+
62
+ capture do
63
+ concat(govuk_label(attribute, govuk_field_options[:label][:text], **govuk_field_options[:label][:options]))
64
+ concat(govuk_hint(govuk_field_options[:hint][:text], **govuk_field_options[:hint][:options])) if govuk_field_options[:hint]
65
+ concat(display_error_message)
66
+ yield(govuk_field_options[field_key])
67
+ end
68
+ end
69
+ end
70
+
71
+ # Generates the HTML to wrap arround a GDS input field component using an ActionView::Helpers::FormBuilder.
72
+ # Unlike {govuk_field}, the method will be able to automatically determine if the error message needs to be shown.
73
+ #
74
+ # @param type [Symbol] the type of the field
75
+ # @param form [ActionView::Helpers::FormBuilder] :form the form builder used to create the label
76
+ # @param attribute [String, Symbol] the attribute of the field
77
+ # @param govuk_field_options [Hash] options that will be used for the parts of the form group, label, hint and field
78
+ #
79
+ # @option govuk_field_options [Hash] :form_group_options ({}) the options for govuk_form_group {govuk_form_group}
80
+ # @option govuk_field_options [Hash] :label the parameters that will be used to create the label for the field:
81
+ # - +:text+ (required) - the label text
82
+ # - +:options+ - default: { } - the options for govuk_label {govuk_label}
83
+ # @option govuk_field_options [Hash] :hint (nil) the parameters that will be used to create the hint for the field
84
+ # - +:text+ (required) - the hint text
85
+ # - +:options+ - default: { } - the options for govuk_hint {govuk_hint}
86
+ # If no hint is given then no hint will be rendered
87
+ # @option govuk_field_options [Hash] :field_options ({}) the options that will be used when rendering the field.
88
+ # For more details look at a module that uses +Field+.
89
+ #
90
+ # @yield the field HTML
91
+ #
92
+ # @yieldparam govuk_field_options [Hash] the HTML options used when rendering the field
93
+ # @yieldparam error_message [ActiveSupport::SafeBuffer] used by the field to indicate if there is an error
94
+ #
95
+ # @return (see govuk_field)
96
+
97
+ def govuk_field_with_form(type, form, attribute, **govuk_field_options)
98
+ field_key = :"#{type}_options"
99
+
100
+ set_label_for_if_custom_id(field_key, govuk_field_options)
101
+ set_hint_id(attribute, govuk_field_options)
102
+
103
+ govuk_form_group_with_model(form.object, attribute, **(govuk_field_options[:form_group_options] || {})) do |display_error_message|
104
+ set_field_described_by(field_key, attribute, display_error_message, govuk_field_options)
105
+
106
+ capture do
107
+ concat(govuk_label_with_form(form, attribute, govuk_field_options[:label][:text], **(govuk_field_options[:label][:options] || {})))
108
+ concat(govuk_hint(govuk_field_options[:hint][:text], **govuk_field_options[:hint][:options])) if govuk_field_options[:hint]
109
+ concat(display_error_message)
110
+ yield(govuk_field_options[field_key], display_error_message)
111
+ end
112
+ end
113
+ end
114
+
115
+ # Generates the HTML to wrap arround a GDS input fields component.
116
+ # These are inputs that require being wrapped in a fieldset, for example radio buttons.
117
+ #
118
+ # @param type [Symbol] the type of the fields
119
+ # @param attribute [String, Symbol] the attribute of the fields
120
+ # @param error_message [String] the error message to be displayed
121
+ # @param govuk_fields_options [Hash] options that will be used for the parts of the fieldset, form group, hint and fields
122
+ #
123
+ # @option govuk_fields_options [Hash] :form_group_options ({}) the options for govuk_form_group {govuk_form_group}
124
+ # @option govuk_fields_options [Hash] :fieldset_options ({}) the options for govuk_fieldset {govuk_fieldset}
125
+ # @option govuk_fields_options [Hash] :hint (nil) the parameters that will be used to create the hint for the fields
126
+ # - +:text+ (required) - the hint text
127
+ # - +:options+ - default: { } - the options for govuk_hint {govuk_hint}
128
+ # If no hint is given then no hint will be rendered
129
+ # @option govuk_fields_options [Hash] :field_options ({}) the options that will be used when rendering the fields.
130
+ # For more details look at a module that uses +Field+.
131
+ #
132
+ # @yield the fields HTML
133
+ #
134
+ # @yieldparam govuk_fields_options [Hash] the HTML options used when rendering the fields
135
+ #
136
+ # @return [ActiveSupport::SafeBuffer] the HTML that wraps arround the fields
137
+
138
+ def govuk_fields(type, attribute, error_message = nil, **govuk_fields_options)
139
+ field_key = :"#{type}_options"
140
+
141
+ set_hint_id(attribute, govuk_fields_options)
142
+
143
+ govuk_form_group(attribute, error_message, **(govuk_fields_options[:form_group_options] || {})) do |display_error_message|
144
+ set_field_described_by(:fieldset_options, attribute, error_message, govuk_fields_options)
145
+ (govuk_fields_options[field_key] ||= {})[:attributes] ||= {}
146
+
147
+ govuk_fieldset(**govuk_fields_options[:fieldset_options]) do
148
+ capture do
149
+ concat(govuk_hint(govuk_fields_options[:hint][:text], **govuk_fields_options[:hint][:options])) if govuk_fields_options[:hint]
150
+ concat(display_error_message)
151
+ yield(govuk_fields_options[field_key])
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ # Generates the HTML to wrap arround a GDS input fields component using an ActionView::Helpers::FormBuilder.
158
+ # These are inputs that require being wrapped in a fieldset, for example radio buttons.
159
+ #
160
+ # Unlike {govuk_fields}, the method will be able to automatically determine if the error message needs to be shown.
161
+ #
162
+ # @param type [Symbol] the type of the fields
163
+ # @param form [ActionView::Helpers::FormBuilder] :form the form builder used to create the label
164
+ # @param attribute [String, Symbol] the attribute of the fields
165
+ # @param govuk_fields_options [Hash] options that will be used for the parts of the fieldset, form group, hint and fields
166
+ #
167
+ # @option govuk_fields_options [Hash] :form_group_options ({}) the options for govuk_form_group {govuk_form_group}
168
+ # @option govuk_fields_options [Hash] :fieldset_options ({}) the options for govuk_fieldset {govuk_fieldset}
169
+ # @option govuk_fields_options [Hash] :hint (nil) the parameters that will be used to create the hint for the fields
170
+ # - +:text+ (required) - the hint text
171
+ # - +:options+ - default: { } - the options for govuk_hint {govuk_hint}
172
+ # If no hint is given then no hint will be rendered
173
+ # @option govuk_fields_options [Hash] :field_options ({}) the options that will be used when rendering the fields.
174
+ # For more details look at a module that uses +Field+.
175
+ #
176
+ # @yield the fields HTML
177
+ #
178
+ # @yieldparam govuk_fields_options [Hash] the HTML options used when rendering the fields
179
+ #
180
+ # @return (see govuk_fields)
181
+
182
+ def govuk_fields_with_form(type, form, attribute, **govuk_fields_options)
183
+ field_key = :"#{type}_options"
184
+
185
+ set_hint_id(attribute, govuk_fields_options)
186
+
187
+ govuk_form_group_with_model(form.object, attribute, **(govuk_fields_options[:form_group_options] || {})) do |display_error_message|
188
+ set_field_described_by(:fieldset_options, attribute, display_error_message, govuk_fields_options)
189
+ (govuk_fields_options[field_key] ||= {})[:attributes] ||= {}
190
+
191
+ govuk_fieldset(**govuk_fields_options[:fieldset_options]) do
192
+ capture do
193
+ concat(govuk_hint(govuk_fields_options[:hint][:text], **govuk_fields_options[:hint][:options])) if govuk_fields_options[:hint]
194
+ concat(display_error_message)
195
+ yield(govuk_fields_options[field_key])
196
+ end
197
+ end
198
+ end
199
+ end
200
+
201
+ private
202
+
203
+ # Sets the label +for+ if a custom ID has been given for the field.
204
+ #
205
+ # @param govuk_field_options [Hash] see {govuk_field} for details
206
+
207
+ def set_label_for_if_custom_id(field_key, govuk_field_options)
208
+ field_id = govuk_field_options.dig(field_key, :attributes, :id)
209
+
210
+ govuk_field_options[:label][:options] ||= {}
211
+ (govuk_field_options[:label][:options][:attributes] ||= {}).merge!({ for: field_id }) if field_id
212
+ end
213
+
214
+ # Sets the hint ID if there is a hint, and the ID for the hint has not been sent
215
+ #
216
+ # @param attribute [String, Symbol] the attribute of the field
217
+ # @param govuk_field_options [Hash] see {govuk_field} for details
218
+
219
+ def set_hint_id(attribute, govuk_field_options)
220
+ return if !govuk_field_options[:hint] || govuk_field_options.dig(:hint, :options, :attributes, :id)
221
+
222
+ govuk_field_options[:hint][:options] ||= {}
223
+ (govuk_field_options[:hint][:options][:attributes] ||= {}).merge!({ id: "#{attribute}-hint" })
224
+ end
225
+
226
+ # Adds the aira-describedby attribute for the field
227
+ # if there is a hint or an error message
228
+ #
229
+ # @param attribute [String, Symbol] the attribute of the input
230
+ # @param error_message [String] used to indicate if there is an error
231
+ # @param govuk_field_options [Hash] see {#govuk_field} for details
232
+
233
+ def set_field_described_by(field_key, attribute, error_message, govuk_field_options)
234
+ aria_described_by = []
235
+ aria_described_by << govuk_field_options.dig(field_key, :attributes, :aria, :describedby)
236
+ aria_described_by << govuk_field_options[:hint][:options][:attributes][:id] if govuk_field_options[:hint]
237
+ aria_described_by << "#{attribute}-error" if error_message
238
+ aria_described_by.compact!
239
+
240
+ govuk_field_options[field_key] ||= {}
241
+ govuk_field_options[field_key][:attributes] ||= {}
242
+
243
+ return unless aria_described_by.any?
244
+
245
+ (govuk_field_options[field_key][:attributes][:aria] ||= {}).merge!({ describedby: aria_described_by.join(' ') })
246
+ end
247
+
248
+ # Sets the hint classes and adds the aira-describedby attribute for a fields item
249
+ #
250
+ # @param type [String] the type of the item
251
+ # @param attribute [String, Symbol] the attribute of the item
252
+ # @param item [Hash] the options for that item
253
+
254
+ def set_item_options_for_hint(type, attribute, item)
255
+ (item[:hint][:options] ||= {})[:attributes] ||= {}
256
+ item[:hint][:options][:classes] = "govuk-#{type}__hint #{item[:hint][:options][:classes]}".rstrip
257
+ item[:hint][:options][:attributes][:id] ||= "#{attribute}_#{item[:value]}-item-hint"
258
+
259
+ (item[:attributes][:aria] ||= {})[:describedby] = item[:hint][:options][:attributes][:id]
260
+ end
261
+ end
262
+ end
263
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+
5
+ module CrownMarketplaceUtils
6
+ module GovUkHelper
7
+ # = GOV.UK Fieldset
8
+ #
9
+ # This helper is used for generating the fieldset component from the
10
+ # {https://design-system.service.gov.uk/components/fieldset GDS - Components - Fieldset}
11
+
12
+ module Fieldset
13
+ include ActionView::Context
14
+ include ActionView::Helpers::TagHelper
15
+ include ActionView::Helpers::TextHelper
16
+
17
+ # Generates the HTML for the GOV.UK Fieldset component
18
+ #
19
+ # @param govuk_fieldset_options [Hash] options that will be used in customising the HTML
20
+ #
21
+ # @option govuk_fieldset_options [String] :classes additional CSS classes for the fieldset HTML
22
+ # @option govuk_fieldset_options [Hash] :legend options for the legend which are used in {#govuk_legend}
23
+ # @option govuk_fieldset_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
24
+ #
25
+ # @yield HTML that will be contained within the 'govuk-fieldset' div and under the legend
26
+ #
27
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Fieldset
28
+ # which can then be rendered on the page
29
+
30
+ def govuk_fieldset(**govuk_fieldset_options)
31
+ govuk_fieldset_classes = ['govuk-fieldset']
32
+ govuk_fieldset_classes << govuk_fieldset_options[:classes]
33
+ govuk_fieldset_options[:attributes] ||= {}
34
+
35
+ tag.fieldset(class: govuk_fieldset_classes, **govuk_fieldset_options[:attributes]) do
36
+ capture do
37
+ concat(govuk_legend(govuk_fieldset_options[:legend])) if govuk_fieldset_options[:legend]
38
+ concat(yield)
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ # Generates the HTML for the Legend as part of {#govuk_fieldset}
46
+ #
47
+ # @param govuk_legend_options [Hash] options that will be used in the legend
48
+ #
49
+ # @option govuk_legend_options [String] :classes additional CSS classes for the legend HTML
50
+ # @option govuk_legend_options [String] :text the text for the legend
51
+ # @option govuk_legend_options [boolean] :is_page_heading (false) if the legend is also the heading it will rendered in a h1
52
+ # @option govuk_legend_options [Hash] :caption an optional hash with the +text+ and +classes+ that will be used
53
+ # to render a caption before the h1 if the legend is a page heading
54
+ #
55
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Fieldset
56
+ # which can then be rendered on the page
57
+
58
+ def govuk_legend(govuk_legend_options)
59
+ govuk_legend_classes = ['govuk-fieldset__legend']
60
+ govuk_legend_classes << govuk_legend_options[:classes]
61
+
62
+ tag.legend(class: govuk_legend_classes) do
63
+ if govuk_legend_options[:is_page_heading]
64
+ capture do
65
+ concat(tag.span(govuk_legend_options[:caption][:text], class: govuk_legend_options[:caption][:classes])) if govuk_legend_options[:caption]
66
+ concat(tag.h1(govuk_legend_options[:text], class: 'govuk-fieldset__heading'))
67
+ end
68
+ else
69
+ govuk_legend_options[:text]
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'error_message'
4
+
5
+ module CrownMarketplaceUtils
6
+ module GovUkHelper
7
+ # = GOV.UK FormGroup
8
+ #
9
+ # This helper is used for generating the form group component from the Government Design Systems
10
+
11
+ module FormGroup
12
+ include ErrorMessage
13
+
14
+ # Generates the HTML for the GOV.UK Form Group component
15
+ #
16
+ # @param attribute [String, Symbol] the attribute that the form group is for
17
+ # @param error_message [String] the error message to be displayed
18
+ # @param govuk_form_group_options [Hash] options that will be used in customising the HTML
19
+ #
20
+ # @option govuk_form_group_options [String] :classes additional CSS classes for the form group HTML
21
+ # @option govuk_form_group_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
22
+ #
23
+ # @yield HTML that will be contained within the 'govuk-form-group' div
24
+ #
25
+ # @yieldparam displayed_error_message [ActiveSupport::SafeBuffer] the HTML for the error message (if there is one)
26
+ #
27
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Form Group
28
+ # which can then be rendered on the page
29
+
30
+ def govuk_form_group(attribute, error_message = nil, **govuk_form_group_options)
31
+ govuk_form_group_classes = ['govuk-form-group']
32
+ govuk_form_group_classes += ['govuk-form-group--error'] if error_message
33
+ govuk_form_group_classes << govuk_form_group_options[:classes]
34
+ govuk_form_group_options[:attributes] ||= {}
35
+
36
+ tag.div(class: govuk_form_group_classes, id: "#{attribute}-form-group", **govuk_form_group_options[:attributes]) do
37
+ yield((govuk_error_message(error_message, attribute) if error_message))
38
+ end
39
+ end
40
+
41
+ # Generates the HTML for the GOV.UK Form Group component using an ActiveModel
42
+ #
43
+ # @param model [ActiveModel] model that will be used to find an error message
44
+ # @param attribute [String, Symbol] the attribute that the form group is for
45
+ # @param govuk_form_group_options [Hash] options that will be used in customising the HTML
46
+ #
47
+ # @option (see #govuk_form_group)
48
+ #
49
+ # @yield (see #govuk_form_group)
50
+ #
51
+ # @yieldparam (see #govuk_form_group)
52
+ #
53
+ # @return (see #govuk_form_group)
54
+
55
+ def govuk_form_group_with_model(model, attribute, **govuk_form_group_options, &block)
56
+ govuk_form_group(attribute, model.errors[attribute].first, **govuk_form_group_options, &block)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+
5
+ module CrownMarketplaceUtils
6
+ module GovUkHelper
7
+ # = GOV.UK Header
8
+ #
9
+ # This helper is used for generating the header component from the
10
+ # {https://design-system.service.gov.uk/components/header GDS - Components - Header}
11
+
12
+ module Header
13
+ include ActionView::Context
14
+ include ActionView::Helpers::FormTagHelper
15
+ include ActionView::Helpers::TagHelper
16
+ include ActionView::Helpers::TextHelper
17
+ include ActionView::Helpers::UrlHelper
18
+
19
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
20
+
21
+ # Generates the HTML for the GOV.UK Header component
22
+ #
23
+ # @param govuk_header_options [Hash] options that will be used in customising the HTML
24
+ #
25
+ # @option govuk_header_options [String] :classes additional CSS classes for the header HTML
26
+ # @option govuk_header_options [Hash] :container_options (see: {govuk_header_container})
27
+ # @option govuk_header_options [Hash] :service_options (see: {govuk_header_service_name})
28
+ # @option govuk_header_options [Hash] :navigation_options (see: {govuk_header_navigation})
29
+ # @option govuk_header_options [Hash] :attributes ({data: { module: 'govuk-header' }})
30
+ # any additional attributes that will added as part of the HTML
31
+ #
32
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Header
33
+ # which can then be rendered on the page
34
+
35
+ def govuk_header(**govuk_header_options)
36
+ govuk_header_classes = ['govuk-header']
37
+ govuk_header_classes << govuk_header_options[:classes]
38
+ govuk_header_options[:attributes] ||= {}
39
+ (govuk_header_options[:attributes][:data] ||= {}).merge!({ module: 'govuk-header' })
40
+
41
+ tag.header(class: govuk_header_classes, role: 'banner', **govuk_header_options[:attributes]) do
42
+ capture do
43
+ concat(govuk_header_container(govuk_header_options[:container_options] || {}))
44
+ if govuk_header_options[:service_options].present? || govuk_header_options[:navigation_options].present?
45
+ concat(tag.div(class: 'govuk-header__content') do
46
+ capture do
47
+ concat(govuk_header_service_name(service_options)) if govuk_header_options[:service_options].present?
48
+ concat(govuk_header_navigation(navigation_options)) if govuk_header_options[:navigation_options].present?
49
+ end
50
+ end)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ # rubocop:enable Metrics/CyclomaticComplexity
57
+
58
+ private
59
+
60
+ # Generates the header container with the logo for {govuk_header}
61
+ #
62
+ # @param container_options [Hash] options that will be used in customising the HTML
63
+ #
64
+ # @option container_options [String] :classes additional CSS classes for the container HTML
65
+ # @option container_options [String] :home_url the URL of the homepage. Defaults to +/+
66
+ # @option container_options [String] :product_name used when the product name follows on directly from ‘GOV.UK’
67
+ # @option container_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
68
+ #
69
+ # @return [ActiveSupport::SafeBuffer] the HTML for the header container which is used in {govuk_header}
70
+
71
+ def govuk_header_container(container_options)
72
+ govuk_header_classes = ['govuk-header__container']
73
+ govuk_header_classes << (container_options[:classes] || 'govuk-width-container')
74
+
75
+ tag.div(class: govuk_header_classes) do
76
+ tag.div(class: 'govuk-header__logo') do
77
+ link_to(container_options[:home_url] || '/', class: 'govuk-header__link govuk-header__link--homepage') do
78
+ capture do
79
+ concat(tag.span(class: 'govuk-header__logotype') do
80
+ capture do
81
+ concat(tag.svg(class: 'govuk-header__logotype-crown', xmlns: 'http://www.w3.org/2000/svg', height: '30', width: '36', aria: { hidden: 'true' }, focusable: 'false', viewBox: '0 0 132 97') do
82
+ tag.path(fill: 'currentColor', 'fill-rule': 'evenodd', d: 'M25 30.2c3.5 1.5 7.7-.2 9.1-3.7 1.5-3.6-.2-7.8-3.9-9.2-3.6-1.4-7.6.3-9.1 3.9-1.4 3.5.3 7.5 3.9 9zM9 39.5c3.6 1.5 7.8-.2 9.2-3.7 1.5-3.6-.2-7.8-3.9-9.1-3.6-1.5-7.6.2-9.1 3.8-1.4 3.5.3 7.5 3.8 9zM4.4 57.2c3.5 1.5 7.7-.2 9.1-3.8 1.5-3.6-.2-7.7-3.9-9.1-3.5-1.5-7.6.3-9.1 3.8-1.4 3.5.3 7.6 3.9 9.1zm38.3-21.4c3.5 1.5 7.7-.2 9.1-3.8 1.5-3.6-.2-7.7-3.9-9.1-3.6-1.5-7.6.3-9.1 3.8-1.3 3.6.4 7.7 3.9 9.1zm64.4-5.6c-3.6 1.5-7.8-.2-9.1-3.7-1.5-3.6.2-7.8 3.8-9.2 3.6-1.4 7.7.3 9.2 3.9 1.3 3.5-.4 7.5-3.9 9zm15.9 9.3c-3.6 1.5-7.7-.2-9.1-3.7-1.5-3.6.2-7.8 3.7-9.1 3.6-1.5 7.7.2 9.2 3.8 1.5 3.5-.3 7.5-3.8 9zm4.7 17.7c-3.6 1.5-7.8-.2-9.2-3.8-1.5-3.6.2-7.7 3.9-9.1 3.6-1.5 7.7.3 9.2 3.8 1.3 3.5-.4 7.6-3.9 9.1zM89.3 35.8c-3.6 1.5-7.8-.2-9.2-3.8-1.4-3.6.2-7.7 3.9-9.1 3.6-1.5 7.7.3 9.2 3.8 1.4 3.6-.3 7.7-3.9 9.1zM69.7 17.7l8.9 4.7V9.3l-8.9 2.8c-.2-.3-.5-.6-.9-.9L72.4 0H59.6l3.5 11.2c-.3.3-.6.5-.9.9l-8.8-2.8v13.1l8.8-4.7c.3.3.6.7.9.9l-5 15.4v.1c-.2.8-.4 1.6-.4 2.4 0 4.1 3.1 7.5 7 8.1h.2c.3 0 .7.1 1 .1.4 0 .7 0 1-.1h.2c4-.6 7.1-4.1 7.1-8.1 0-.8-.1-1.7-.4-2.4V34l-5.1-15.4c.4-.2.7-.6 1-.9zM66 92.8c16.9 0 32.8 1.1 47.1 3.2 4-16.9 8.9-26.7 14-33.5l-9.6-3.4c1 4.9 1.1 7.2 0 10.2-1.5-1.4-3-4.3-4.2-8.7L108.6 76c2.8-2 5-3.2 7.5-3.3-4.4 9.4-10 11.9-13.6 11.2-4.3-.8-6.3-4.6-5.6-7.9 1-4.7 5.7-5.9 8-.5 4.3-8.7-3-11.4-7.6-8.8 7.1-7.2 7.9-13.5 2.1-21.1-8 6.1-8.1 12.3-4.5 20.8-4.7-5.4-12.1-2.5-9.5 6.2 3.4-5.2 7.9-2 7.2 3.1-.6 4.3-6.4 7.8-13.5 7.2-10.3-.9-10.9-8-11.2-13.8 2.5-.5 7.1 1.8 11 7.3L80.2 60c-4.1 4.4-8 5.3-12.3 5.4 1.4-4.4 8-11.6 8-11.6H55.5s6.4 7.2 7.9 11.6c-4.2-.1-8-1-12.3-5.4l1.4 16.4c3.9-5.5 8.5-7.7 10.9-7.3-.3 5.8-.9 12.8-11.1 13.8-7.2.6-12.9-2.9-13.5-7.2-.7-5 3.8-8.3 7.1-3.1 2.7-8.7-4.6-11.6-9.4-6.2 3.7-8.5 3.6-14.7-4.6-20.8-5.8 7.6-5 13.9 2.2 21.1-4.7-2.6-11.9.1-7.7 8.8 2.3-5.5 7.1-4.2 8.1.5.7 3.3-1.3 7.1-5.7 7.9-3.5.7-9-1.8-13.5-11.2 2.5.1 4.7 1.3 7.5 3.3l-4.7-15.4c-1.2 4.4-2.7 7.2-4.3 8.7-1.1-3-.9-5.3 0-10.2l-9.5 3.4c5 6.9 9.9 16.7 14 33.5 14.8-2.1 30.8-3.2 47.7-3.2z')
83
+ end)
84
+ concat(tag.span('GOV.UK', class: 'govuk-header__logotype-text'))
85
+ end
86
+ end)
87
+ concat(tag.span(container_options[:product_name], class: 'govuk-header__product-name')) if container_options[:product_name]
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ # rubocop:enable Metrics/AbcSize
95
+
96
+ # Generates the service name for {govuk_header}
97
+ #
98
+ # @param service_options [Hash] options that will be used in customising the HTML
99
+ #
100
+ # @option service_options [String] :service_name the name of your service, included in the header
101
+ # @option service_options [String] :service_url URL for the service name anchor
102
+ #
103
+ # @return [ActiveSupport::SafeBuffer] the HTML for the service name which is used in {govuk_header}
104
+
105
+ def govuk_header_service_name(service_options)
106
+ if service_options[:service_url]
107
+ link_to(service_options[:service_name], service_options[:service_url], class: 'govuk-header__link govuk-header__service-name')
108
+ else
109
+ tag.span(service_options[:service_name], class: 'govuk-header__service-name')
110
+ end
111
+ end
112
+
113
+ # Generates the navigation section for {govuk_header}
114
+ #
115
+ # @param navigation_options [Hash] options that will be used in customising the HTML
116
+ #
117
+ # @option navigation_options [String] :classes additional CSS classes for the navigation HTML
118
+ # @option navigation_options [String] :menu_button_text text of the button that opens the mobile navigation menu.
119
+ # By default, this is set to +'Menu'+.
120
+ # @option navigation_options [String] :menu_button_label text for the aria-label attribute of the button that opens the mobile navigation.
121
+ # Defaults to +'Show or hide menu'+.
122
+ # @option navigation_options [Array] :items the navigation items that will be rendered on the page (see {govuk_header_navigation_item})
123
+ #
124
+ # @return [ActiveSupport::SafeBuffer] the HTML for the navigation section which is used in {govuk_header}
125
+
126
+ def govuk_header_navigation(navigation_options)
127
+ menu_button_text = navigation_options[:menu_button_text] || 'Menu'
128
+ menu_button_label = navigation_options[:menu_button_label] || 'Show or hide menu'
129
+
130
+ govuk_header_navigation_classes = ['govuk-header__navigation']
131
+ govuk_header_navigation_classes << navigation_options[:classes]
132
+
133
+ tag.nav(class: govuk_header_navigation_classes, aria: { label: menu_button_text }) do
134
+ capture do
135
+ concat(button_tag(menu_button_text, class: 'govuk-header__menu-button govuk-js-header-toggle', type: 'button', hidden: true, aria: { controls: 'navigation', label: menu_button_label, }))
136
+ concat(tag.ul(id: 'navigation', class: 'govuk-header__navigation-list') do
137
+ capture do
138
+ navigation_options[:items].each do |navigation_item|
139
+ concat(govuk_header_navigation_item(navigation_item))
140
+ end
141
+ end
142
+ end)
143
+ end
144
+ end
145
+ end
146
+
147
+ # Generates a navigation item for {govuk_header_navigation}
148
+ #
149
+ # @param navigation_item [Hash] options that will be used in customising the HTML
150
+ #
151
+ # @option navigation_item [Boolean] :active flag to mark the navigation item as active or not
152
+ # @option navigation_item [String] :text text for the navigation item
153
+ # @option navigation_item [String] :href URL of the navigation item anchor
154
+ # @option navigation_item [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
155
+ #
156
+ # @return [ActiveSupport::SafeBuffer] the HTML for a navigation item which is used in {govuk_header_navigation}
157
+
158
+ def govuk_header_navigation_item(navigation_item)
159
+ govuk_header_navigation_item_classes = ['govuk-header__navigation-item']
160
+ govuk_header_navigation_item_classes << 'govuk-header__navigation-item--active' if navigation_item[:active]
161
+
162
+ tag.li(class: govuk_header_navigation_item_classes) do
163
+ if navigation_item[:href]
164
+ link_to(navigation_item[:text], navigation_item[:href], class: 'govuk-header__link', **(navigation_item[:attributes] || {}))
165
+ else
166
+ concat(navigation_item[:text])
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'action_view'
4
+
3
5
  module CrownMarketplaceUtils
4
6
  module GovUkHelper
5
7
  # = GOV.UK Hint
@@ -7,22 +9,26 @@ module CrownMarketplaceUtils
7
9
  # This helper is used for generating the hint text component from the Government Design Systems
8
10
 
9
11
  module Hint
12
+ include ActionView::Context
13
+ include ActionView::Helpers::TagHelper
14
+
10
15
  # Generates the HTML for the GOV.UK Hint component
11
16
  #
12
17
  # @param hint_text [String] the hint text
13
- # @param hint_options [Hash] options that will be used in customising the HTML
18
+ # @param govuk_hint_options [Hash] options that will be used in customising the HTML
14
19
  #
15
- # @option hint_options [String] :classes additional CSS classes for the hint HTML
16
- # @option hint_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
20
+ # @option govuk_hint_options [String] :classes additional CSS classes for the hint HTML
21
+ # @option govuk_hint_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
17
22
  #
18
23
  # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Hint
19
24
  # which can then be rendered on the page
20
25
 
21
- def govuk_hint(hint_text, **hint_options)
26
+ def govuk_hint(hint_text, **govuk_hint_options)
22
27
  govuk_hint_classes = ['govuk-hint']
23
- govuk_hint_classes << hint_options[:classes]
28
+ govuk_hint_classes << govuk_hint_options[:classes]
29
+ govuk_hint_options[:attributes] ||= {}
24
30
 
25
- tag.div(hint_text, class: govuk_hint_classes, **(hint_options[:attributes] || {}))
31
+ tag.div(hint_text, class: govuk_hint_classes, **govuk_hint_options[:attributes])
26
32
  end
27
33
  end
28
34
  end