ccs-frontend_helpers 0.1.0.rc.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 (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,213 @@
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 CCS
9
+ module FrontendHelpers
10
+ module GovUKFrontend
11
+ # = GOV.UK Field
12
+ #
13
+ # This module contains methods to wrap the:
14
+ # - fieldset
15
+ # - form group
16
+ # - label
17
+ # - hint
18
+ # - error message
19
+ # around some kind of input.
20
+ #
21
+ # The wrapper functions in this module are used
22
+ # to create the fields using the structure of a GDS input field component.
23
+
24
+ module Field
25
+ include Fieldset
26
+ include FormGroup
27
+ include Hint
28
+ include Label
29
+
30
+ # Generates the HTML to wrap arround a GDS input field component.
31
+ #
32
+ # @param field [Symbol] the type of the field
33
+ # @param attribute [String, Symbol] the attribute of the field
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 [String] :error_message (nil) the error message to be displayed
37
+ # @option govuk_field_options [ActiveModel] :model (nil) optional model that can be used to find an error message
38
+ # @option govuk_field_options [ActionView::Helpers::FormBuilder] :form (nil) optional form builder used to create
39
+ # the field and find the error message
40
+ # @option govuk_field_options [Hash] :form_group ({}) the options for govuk_form_group {govuk_form_group}
41
+ # @option govuk_field_options [Hash] :label the parameters that will be used to create the label for the field, see {govuk_label}
42
+ # @option govuk_field_options [Hash] :hint (nil) the parameters that will be used to create the hint for the field, see {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 the specific 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
+ # @yieldparam error_message [String] flag to indicate if there are any erros
51
+ #
52
+ # @return [ActiveSupport::SafeBuffer] the HTML that wraps arround the field
53
+
54
+ def govuk_field(field, attribute, **govuk_field_options)
55
+ set_label_for_if_custom_id(field, govuk_field_options)
56
+ set_hint_id(attribute, govuk_field_options)
57
+ error_message = find_field_error_message(attribute, govuk_field_options)
58
+
59
+ govuk_form_group(attribute, error_message: error_message, **(govuk_field_options[:form_group] || {})) do |display_error_message|
60
+ set_field_described_by(field, attribute, error_message, govuk_field_options)
61
+
62
+ concat(govuk_label(attribute, govuk_field_options[:label][:text], form: govuk_field_options[:form], **govuk_field_options[:label]))
63
+ concat(govuk_hint(govuk_field_options[:hint][:text], **govuk_field_options[:hint])) if govuk_field_options[:hint]
64
+ concat(display_error_message)
65
+ yield(govuk_field_options[field], error_message)
66
+ end
67
+ end
68
+
69
+ # Generates the HTML to wrap arround a GDS input fields component.
70
+ # These are inputs that require being wrapped in a fieldset, for example radio buttons.
71
+ #
72
+ # @param field [Symbol] the type of the fields
73
+ # @param attribute [String, Symbol] the attribute of the fields
74
+ # @param govuk_fields_options [Hash] options that will be used for the parts of the fieldset, form group, hint and fields
75
+ #
76
+ # @option govuk_fields_options [String] :error_message (nil) the error message to be displayed
77
+ # @option govuk_fields_options [ActiveModel] :model (nil) optional model that can be used to find an error message
78
+ # @option govuk_fields_options [ActionView::Helpers::FormBuilder] :form (nil) optional form builder used to create
79
+ # the field and find the error message
80
+ # @option govuk_fields_options [Hash] :form_group ({}) the options for govuk_form_group {govuk_form_group}
81
+ # @option govuk_fields_options [Hash] :fieldset ({}) the options for govuk_fieldset {govuk_fieldset}
82
+ # @option govuk_fields_options [Hash] :hint (nil) the parameters that will be used to create the hint for the field, see {govuk_hint}.
83
+ # If no hint is given then no hint will be rendered
84
+ # @option govuk_fields_options [Hash] :field_options ({}) the options that will be used when rendering the fields.
85
+ # For more details look at a module that uses +Field+.
86
+ #
87
+ # @yield the fields HTML
88
+ #
89
+ # @yieldparam govuk_fields_options [Hash] the HTML options used when rendering the fields
90
+ # @yieldparam error_message [String] flag to indicate if there are any erros
91
+ #
92
+ # @return [ActiveSupport::SafeBuffer] the HTML that wraps arround the fields
93
+
94
+ def govuk_fields(field, attribute, **govuk_fields_options)
95
+ set_hint_id(attribute, govuk_fields_options)
96
+ error_message = find_field_error_message(attribute, govuk_fields_options)
97
+
98
+ govuk_form_group(attribute, error_message: error_message, **(govuk_fields_options[:form_group] || {})) do |display_error_message|
99
+ set_field_described_by(:fieldset, attribute, error_message, govuk_fields_options)
100
+ (govuk_fields_options[field] ||= {})[:attributes] ||= {}
101
+
102
+ govuk_fieldset(**govuk_fields_options[:fieldset]) do
103
+ concat(govuk_hint(govuk_fields_options[:hint][:text], **govuk_fields_options[:hint])) if govuk_fields_options[:hint]
104
+ concat(display_error_message)
105
+ yield(govuk_fields_options[field], error_message)
106
+ end
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ # If present, will find the error message for the field
113
+ #
114
+ # @param attribute [String, Symbol] the attribute of the fields
115
+ #
116
+ # @option govuk_field_options [String] :error_message (nil) the error message to be displayed
117
+ # @option govuk_field_options [ActiveModel] :model (nil) optional model that can be used to find an error message
118
+ # @option govuk_field_options [ActionView::Helpers::FormBuilder] :form (nil) optional form builder used to create
119
+ # the field and find the error message
120
+ #
121
+ # @return [String] the error message
122
+
123
+ def find_field_error_message(attribute, govuk_field_options)
124
+ if govuk_field_options[:model]
125
+ govuk_field_options[:model].errors[attribute].first
126
+ elsif govuk_field_options[:form]
127
+ govuk_field_options[:form].object.errors[attribute].first
128
+ else
129
+ govuk_field_options[:error_message]
130
+ end
131
+ end
132
+
133
+ # Sets the label +for+ if a custom ID has been given for the field.
134
+ #
135
+ # @param govuk_field_options [Hash] see {govuk_field} for details
136
+
137
+ def set_label_for_if_custom_id(field, govuk_field_options)
138
+ field_id = govuk_field_options.dig(field, :attributes, :id)
139
+
140
+ govuk_field_options[:label] ||= {}
141
+ (govuk_field_options[:label][:attributes] ||= {})[:for] = field_id if field_id
142
+ end
143
+
144
+ # Sets the hint ID if there is a hint, and the ID for the hint has not been sent
145
+ #
146
+ # @param attribute [String, Symbol] the attribute of the field
147
+ # @param govuk_field_options [Hash] see {govuk_field} for details
148
+
149
+ def set_hint_id(attribute, govuk_field_options)
150
+ return if !govuk_field_options[:hint] || govuk_field_options.dig(:hint, :attributes, :id)
151
+
152
+ govuk_field_options[:hint] ||= {}
153
+ (govuk_field_options[:hint][:attributes] ||= {})[:id] = "#{attribute}-hint"
154
+ end
155
+
156
+ # Adds the aira-describedby attribute for the field
157
+ # if there is a hint or an error message
158
+ #
159
+ # @param attribute [String, Symbol] the attribute of the input
160
+ # @param error_message [String] used to indicate if there is an error
161
+ # @param govuk_field_options [Hash] see {#govuk_field} for details
162
+
163
+ def set_field_described_by(field, attribute, error_message, govuk_field_options)
164
+ aria_described_by = []
165
+ aria_described_by << govuk_field_options.dig(field, :attributes, :aria, :describedby)
166
+ aria_described_by << govuk_field_options[:hint][:attributes][:id] if govuk_field_options[:hint]
167
+ aria_described_by << "#{attribute}-error" if error_message
168
+ aria_described_by.compact!
169
+
170
+ govuk_field_options[field] ||= {}
171
+ govuk_field_options[field][:attributes] ||= {}
172
+
173
+ return unless aria_described_by.any?
174
+
175
+ (govuk_field_options[field][:attributes][:aria] ||= {})[:describedby] = aria_described_by.join(' ')
176
+ end
177
+
178
+ # Sets the hint attributes and adds the aira-describedby attribute for a fields item
179
+ #
180
+ # @param type [String] the type of the item
181
+ # @param attribute [String, Symbol] the attribute of the item
182
+ # @param item [Hash] the options for that item
183
+
184
+ def set_item_options_for_hint(type, attribute, item)
185
+ return unless item[:hint]
186
+
187
+ (item[:hint] ||= {})[:attributes] ||= {}
188
+ item[:hint][:classes] = "govuk-#{type}__hint #{item[:hint][:classes]}".rstrip
189
+ item[:hint][:attributes][:id] ||= "#{attribute}_#{item[:value]}-item-hint"
190
+
191
+ (item[:attributes][:aria] ||= {})[:describedby] = item[:hint][:attributes][:id]
192
+ end
193
+
194
+ # Sets the conditional attributes and adds the data-aira-controls attribute for a fields item
195
+ #
196
+ # @param type [String] the type of the item
197
+ # @param attribute [String, Symbol] the attribute of the item
198
+ # @param item [Hash] the options for that item
199
+
200
+ def set_conditional_item_options(type, attribute, item)
201
+ return unless item[:conditional]
202
+
203
+ item[:conditional][:attributes] ||= {}
204
+ item[:conditional][:attributes][:class] = "govuk-#{type}__conditional #{"govuk-#{type}__conditional--hidden" unless item[:checked]}".rstrip
205
+ item[:conditional][:attributes][:id] ||= sanitize_to_id("#{attribute}_#{item[:value]}_conditional")
206
+ (item[:attributes][:data] ||= {})[:'aria-controls'] = item[:conditional][:attributes][:id]
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ ActionView::Base.field_error_proc = proc { |html_tag, _instance| html_tag }
213
+ end
@@ -0,0 +1,71 @@
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 Fieldset
11
+ #
12
+ # This helper is used for generating the fieldset component from the
13
+ # {https://design-system.service.gov.uk/components/fieldset GDS - Components - Fieldset}
14
+
15
+ module Fieldset
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 Fieldset component
22
+ #
23
+ # @param govuk_fieldset_options [Hash] options that will be used in customising the HTML
24
+ #
25
+ # @option govuk_fieldset_options [String] :classes additional CSS classes for the fieldset HTML
26
+ # @option govuk_fieldset_options [Hash] :legend options for the legend which are used in {#govuk_legend}
27
+ # @option govuk_fieldset_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
28
+ #
29
+ # @yield HTML that will be contained within the 'govuk-fieldset' div and under the legend
30
+ #
31
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Fieldset
32
+ # which can then be rendered on the page
33
+
34
+ def govuk_fieldset(**govuk_fieldset_options)
35
+ initialise_attributes_and_set_classes(govuk_fieldset_options, 'govuk-fieldset')
36
+
37
+ tag.fieldset(**govuk_fieldset_options[:attributes]) do
38
+ concat(govuk_legend(govuk_fieldset_options[:legend])) if govuk_fieldset_options[:legend]
39
+ yield
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
+ tag.legend(class: "govuk-fieldset__legend #{govuk_legend_options[:classes]}".rstrip) do
60
+ if govuk_legend_options[:is_page_heading]
61
+ concat(tag.span(govuk_legend_options[:caption][:text], class: govuk_legend_options[:caption][:classes])) if govuk_legend_options[:caption]
62
+ concat(tag.h1(govuk_legend_options[:text], class: 'govuk-fieldset__heading'))
63
+ else
64
+ govuk_legend_options[:text]
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,183 @@
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 Footer
11
+ #
12
+ # This helper is used for generating the footer component from the
13
+ # {https://design-system.service.gov.uk/components/footer GDS - Components - Footer}
14
+
15
+ module Footer
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
+ # rubocop:disable Metrics/AbcSize
24
+
25
+ # Generates the HTML for the GOV.UK Footer component
26
+ #
27
+ # @param govuk_footer_options [Hash] options that will be used in customising the HTML
28
+ #
29
+ # @option govuk_footer_options [String] :classes additional CSS classes for the footer HTML
30
+ # @option govuk_footer_options [String] :container_class classes that can be added to the inner container
31
+ # @option govuk_footer_options [Array] :navigation (see: {govuk_footer_navigation})
32
+ # @option govuk_footer_options [Hash] :meta (see: {govuk_footer_meta})
33
+ # @option govuk_footer_options [ActiveSupport::SafeBuffer,String] :content_licence The content licence information. See {govuk_footer_content_licence}
34
+ # @option govuk_footer_options [ActiveSupport::SafeBuffer,String] :copyright The copyright information. See {govuk_footer_copyright}
35
+ # @option govuk_footer_options [Hash] :attributes additional attributes that will added as part of the HTML
36
+ #
37
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Footer
38
+ # which can then be rendered on the page
39
+
40
+ def govuk_footer(**govuk_footer_options)
41
+ initialise_attributes_and_set_classes(govuk_footer_options, 'govuk-footer')
42
+
43
+ govuk_footer_options[:attributes][:role] = 'contentinfo'
44
+
45
+ tag.footer(**govuk_footer_options[:attributes]) do
46
+ tag.div(class: "govuk-width-container #{govuk_footer_options[:container_classes]}".rstrip) do
47
+ if govuk_footer_options[:navigation]
48
+ concat(tag.div(class: 'govuk-footer__navigation') do
49
+ govuk_footer_options[:navigation].each { |navigation_item| concat(govuk_footer_navigation(navigation_item)) }
50
+ end)
51
+ concat(tag.hr(class: 'govuk-footer__section-break'))
52
+ end
53
+ concat(tag.div(class: 'govuk-footer__meta') do
54
+ concat(tag.div(class: 'govuk-footer__meta-item govuk-footer__meta-item--grow') do
55
+ concat(govuk_footer_meta(govuk_footer_options[:meta])) if govuk_footer_options[:meta]
56
+ concat(govuk_footer_logo)
57
+ concat(govuk_footer_content_licence(govuk_footer_options[:content_licence]))
58
+ end)
59
+ concat(govuk_footer_copyright(govuk_footer_options[:copyright]))
60
+ end)
61
+ end
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ # Generates the HTML for the navigation section in {govuk_footer}
68
+ #
69
+ # @param navigation_item [Hash] options that will be used for the navigation section
70
+ #
71
+ # @option navigation_item [String] :title title for a section
72
+ # @option navigation_item [String] :width (default: 'fall') width of each navigation section in the footer
73
+ # @option navigation_item [Integer] :columns amount of columns to display items in navigation section of the footer
74
+ # @option navigation_item [Array] :items array of items to display in the list in navigation section of the footer.
75
+ # Each item can have the following options:
76
+ # - +:text+ list item text
77
+ # - +:href+ list item href
78
+ # - +:attributes+ HTML attributes to add to the link
79
+ #
80
+ # @return [ActiveSupport::SafeBuffer] the HTML for the navigation section in {govuk_footer}
81
+
82
+ def govuk_footer_navigation(navigation_item)
83
+ tag.div(class: "govuk-footer__section govuk-grid-column-#{navigation_item[:width] || 'full'}") do
84
+ concat(tag.h2(navigation_item[:title], class: 'govuk-footer__heading govuk-heading-m'))
85
+ concat(tag.ul(class: "govuk-footer__list #{"govuk-footer__list--columns-#{navigation_item[:columns]}" if navigation_item[:columns]}".rstrip) do
86
+ navigation_item[:items].each do |item|
87
+ concat(tag.li(class: 'govuk-footer__list-item') do
88
+ (item[:attributes] ||= {})[:class] = 'govuk-footer__link'
89
+
90
+ link_to(item[:text], item[:href], **item[:attributes])
91
+ end)
92
+ end
93
+ end)
94
+ end
95
+ end
96
+
97
+ # Generates the HTML for the meta section in {govuk_footer}
98
+ #
99
+ # @param meta [Hash] options that will be used for the meta section
100
+ #
101
+ # @option meta [String] :visually_hidden_title (default: 'Support links') title for a meta item section
102
+ # @option meta [ActiveSupport::SafeBuffer,String] :text text to add to the meta section of the footer,
103
+ # which will appear below any links specified using meta.items
104
+ # @option meta [Array] :items array of items to display in the list in meta section of the footer.
105
+ # Each item can have the following options:
106
+ # - +:text+ list item text
107
+ # - +:href+ list item href
108
+ # - +:attributes+ HTML attributes to add to the link
109
+ #
110
+ # @return [ActiveSupport::SafeBuffer] the HTML for the meta section in {govuk_footer}
111
+
112
+ def govuk_footer_meta(meta)
113
+ concat(tag.h2(meta[:visually_hidden_title] || 'Support links', class: 'govuk-visually-hidden'))
114
+ if meta[:items]
115
+ concat(tag.ul(class: 'govuk-footer__inline-list') do
116
+ meta[:items].each do |meta_item|
117
+ concat(tag.li(class: 'govuk-footer__inline-list-item') do
118
+ (meta_item[:attributes] ||= {})[:class] = 'govuk-footer__link'
119
+
120
+ link_to(meta_item[:text], meta_item[:href], **meta_item[:attributes])
121
+ end)
122
+ end
123
+ end)
124
+ end
125
+ concat(tag.div(meta[:text], class: 'govuk-footer__meta-custom')) if meta[:text]
126
+ end
127
+
128
+ # rubocop:enable Metrics/AbcSize
129
+
130
+ # Generates the logo used in {govuk_footer}
131
+ #
132
+ # @return [ActiveSupport::SafeBuffer]
133
+
134
+ def govuk_footer_logo
135
+ tag.svg(
136
+ class: 'govuk-footer__licence-logo',
137
+ aria: { hidden: 'true' },
138
+ focusable: 'false',
139
+ xmlns: 'http://www.w3.org/2000/svg',
140
+ viewBox: '0 0 483.2 195.7',
141
+ height: '17',
142
+ width: '41'
143
+ ) do
144
+ tag.path(
145
+ fill: 'currentColor',
146
+ d: 'M421.5 142.8V.1l-50.7 32.3v161.1h112.4v-50.7zm-122.3-9.6A47.12 47.12 0 0 1 221 97.8c0-26 21.1-47.1 47.1-47.1 16.7 0 31.4 8.7 39.7 21.8l42.7-27.2A97.63 97.63 0 0 0 268.1 0c-36.5 0-68.3 20.1-85.1 49.7A98 98 0 0 0 97.8 0C43.9 0 0 43.9 0 97.8s43.9 97.8 97.8 97.8c36.5 0 68.3-20.1 85.1-49.7a97.76 97.76 0 0 0 149.6 25.4l19.4 22.2h3v-87.8h-80l24.3 27.5zM97.8 145c-26 0-47.1-21.1-47.1-47.1s21.1-47.1 47.1-47.1 47.2 21 47.2 47S123.8 145 97.8 145'
147
+ )
148
+ end
149
+ end
150
+
151
+ # Generates the content licence used in {govuk_footer}
152
+ #
153
+ # @param content_licence [ActiveSupport::SafeBuffer,String] the content licence information. Defaults to Open Government Licence (OGL) v3 licence
154
+ #
155
+ # @return [ActiveSupport::SafeBuffer] the HTML for the content licence used in {govuk_footer}
156
+
157
+ def govuk_footer_content_licence(content_licence)
158
+ tag.span(class: 'govuk-footer__licence-description') do
159
+ if content_licence
160
+ concat(content_licence)
161
+ else
162
+ concat('All content is available under the')
163
+ concat(link_to('Open Government Licence v3.0', 'https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/', class: 'govuk-footer__link', rel: 'license'))
164
+ concat(', except where otherwise stated')
165
+ end
166
+ end
167
+ end
168
+
169
+ # Generates the copyright used in {govuk_footer}
170
+ #
171
+ # @param copyright [ActiveSupport::SafeBuffer,String] the copyright information, this defaults to Crown Copyright
172
+ #
173
+ # @return [ActiveSupport::SafeBuffer] the HTML for the copyright used in {govuk_footer}
174
+
175
+ def govuk_footer_copyright(copyright)
176
+ tag.div(class: 'govuk-footer__meta-item') do
177
+ link_to(copyright || '© Crown copyright', 'https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/', class: 'govuk-footer__link govuk-footer__copyright-logo')
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'error_message'
4
+
5
+ module CCS
6
+ module FrontendHelpers
7
+ module GovUKFrontend
8
+ # = GOV.UK FormGroup
9
+ #
10
+ # This helper is used for generating the form group component from the Government Design Systems
11
+
12
+ module FormGroup
13
+ include ErrorMessage
14
+
15
+ # Generates the HTML for the GOV.UK Form Group component
16
+ #
17
+ # @param attribute [String, Symbol] the attribute that the form group is for
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 [String] :error_message (nil) the error message to be displayed
22
+ # @option govuk_form_group_options [ActiveModel] :model (nil) model that will be used to find an error message
23
+ # @option govuk_form_group_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-form-group' div
26
+ #
27
+ # @yieldparam displayed_error_message [ActiveSupport::SafeBuffer] the HTML for the error message (if there is one)
28
+ #
29
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Form Group
30
+ # which can then be rendered on the page
31
+
32
+ def govuk_form_group(attribute, **govuk_form_group_options)
33
+ error_message = if govuk_form_group_options[:model]
34
+ model.errors[attribute].first
35
+ else
36
+ govuk_form_group_options[:error_message]
37
+ end
38
+
39
+ initialise_attributes_and_set_classes(govuk_form_group_options, "govuk-form-group #{'govuk-form-group--error' if error_message}".rstrip)
40
+
41
+ govuk_form_group_options[:attributes][:id] ||= "#{attribute}-form-group"
42
+
43
+ tag.div(**govuk_form_group_options[:attributes]) do
44
+ yield((govuk_error_message(error_message, attribute) if error_message))
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end