ccs-frontend_helpers 0.1.0.rc.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -5
  3. data/CHANGELOG.md +2 -4
  4. data/Gemfile +1 -15
  5. data/Gemfile.lock +80 -81
  6. data/ccs-frontend_helpers.gemspec +10 -0
  7. data/lib/ccs/frontend_helpers/ccs_frontend/dashboard_panels.rb +79 -0
  8. data/lib/ccs/frontend_helpers/ccs_frontend/footer.rb +119 -6
  9. data/lib/ccs/frontend_helpers/ccs_frontend/header.rb +183 -6
  10. data/lib/ccs/{components/ccs → frontend_helpers/ccs_frontend}/logo.rb +12 -10
  11. data/lib/ccs/frontend_helpers/ccs_frontend.rb +4 -2
  12. data/lib/ccs/frontend_helpers/govuk_frontend/accordion.rb +95 -8
  13. data/lib/ccs/frontend_helpers/govuk_frontend/back_link.rb +17 -6
  14. data/lib/ccs/frontend_helpers/govuk_frontend/breadcrumbs.rb +54 -6
  15. data/lib/ccs/frontend_helpers/govuk_frontend/button.rb +105 -6
  16. data/lib/ccs/frontend_helpers/govuk_frontend/cookie_banner.rb +114 -6
  17. data/lib/ccs/frontend_helpers/govuk_frontend/details.rb +23 -7
  18. data/lib/ccs/frontend_helpers/govuk_frontend/error_message.rb +32 -11
  19. data/lib/ccs/frontend_helpers/govuk_frontend/error_summary.rb +65 -13
  20. data/lib/ccs/frontend_helpers/govuk_frontend/field/character_count.rb +165 -0
  21. data/lib/ccs/frontend_helpers/govuk_frontend/field/checkboxes.rb +200 -0
  22. data/lib/ccs/frontend_helpers/govuk_frontend/field/date_input.rb +153 -0
  23. data/lib/ccs/frontend_helpers/govuk_frontend/field/file_upload.rb +83 -0
  24. data/lib/ccs/frontend_helpers/govuk_frontend/field/input.rb +153 -0
  25. data/lib/ccs/frontend_helpers/govuk_frontend/field/radios.rb +201 -0
  26. data/lib/ccs/frontend_helpers/govuk_frontend/field/select.rb +124 -0
  27. data/lib/ccs/frontend_helpers/govuk_frontend/field/textarea.rb +106 -0
  28. data/lib/ccs/frontend_helpers/govuk_frontend/field.rb +213 -0
  29. data/lib/ccs/frontend_helpers/govuk_frontend/fieldset.rb +48 -7
  30. data/lib/ccs/frontend_helpers/govuk_frontend/footer.rb +161 -6
  31. data/lib/ccs/frontend_helpers/govuk_frontend/form_group.rb +24 -13
  32. data/lib/ccs/frontend_helpers/govuk_frontend/header.rb +139 -6
  33. data/lib/ccs/frontend_helpers/govuk_frontend/hint.rb +17 -8
  34. data/lib/ccs/frontend_helpers/govuk_frontend/inset_text.rb +21 -7
  35. data/lib/ccs/frontend_helpers/govuk_frontend/label.rb +70 -7
  36. data/lib/ccs/frontend_helpers/govuk_frontend/notification_banner.rb +113 -7
  37. data/lib/ccs/frontend_helpers/govuk_frontend/pagination.rb +314 -6
  38. data/lib/ccs/frontend_helpers/govuk_frontend/panel.rb +28 -7
  39. data/lib/ccs/frontend_helpers/govuk_frontend/phase_banner.rb +27 -8
  40. data/lib/ccs/frontend_helpers/govuk_frontend/skip_link.rb +18 -6
  41. data/lib/ccs/frontend_helpers/govuk_frontend/step_by_step_navigation.rb +186 -7
  42. data/lib/ccs/frontend_helpers/govuk_frontend/summary_list.rb +204 -6
  43. data/lib/ccs/frontend_helpers/govuk_frontend/table.rb +100 -11
  44. data/lib/ccs/frontend_helpers/govuk_frontend/tabs.rb +73 -6
  45. data/lib/ccs/frontend_helpers/govuk_frontend/tag.rb +21 -7
  46. data/lib/ccs/frontend_helpers/govuk_frontend/warning_text.rb +30 -7
  47. data/lib/ccs/frontend_helpers/govuk_frontend.rb +19 -17
  48. data/lib/ccs/frontend_helpers/shared_methods.rb +27 -0
  49. data/lib/ccs/frontend_helpers/version.rb +1 -1
  50. metadata +142 -112
  51. data/.ruby-version +0 -1
  52. data/lib/ccs/components/base.rb +0 -64
  53. data/lib/ccs/components/ccs/dashboard_section/panel.rb +0 -57
  54. data/lib/ccs/components/ccs/dashboard_section.rb +0 -71
  55. data/lib/ccs/components/ccs/footer/link.rb +0 -55
  56. data/lib/ccs/components/ccs/footer/meta.rb +0 -59
  57. data/lib/ccs/components/ccs/footer/navigation.rb +0 -60
  58. data/lib/ccs/components/ccs/footer.rb +0 -95
  59. data/lib/ccs/components/ccs/header/link.rb +0 -60
  60. data/lib/ccs/components/ccs/header/navigation.rb +0 -98
  61. data/lib/ccs/components/ccs/header/service_authentication.rb +0 -53
  62. data/lib/ccs/components/ccs/header.rb +0 -110
  63. data/lib/ccs/components/govuk/accordion/section/content.rb +0 -53
  64. data/lib/ccs/components/govuk/accordion/section/header.rb +0 -57
  65. data/lib/ccs/components/govuk/accordion/section.rb +0 -61
  66. data/lib/ccs/components/govuk/accordion.rb +0 -58
  67. data/lib/ccs/components/govuk/back_link.rb +0 -51
  68. data/lib/ccs/components/govuk/breadcrumbs/link.rb +0 -57
  69. data/lib/ccs/components/govuk/breadcrumbs.rb +0 -55
  70. data/lib/ccs/components/govuk/button.rb +0 -107
  71. data/lib/ccs/components/govuk/cookie_banner/action.rb +0 -60
  72. data/lib/ccs/components/govuk/cookie_banner/message.rb +0 -80
  73. data/lib/ccs/components/govuk/cookie_banner.rb +0 -55
  74. data/lib/ccs/components/govuk/details.rb +0 -53
  75. data/lib/ccs/components/govuk/error_message.rb +0 -60
  76. data/lib/ccs/components/govuk/error_summary/item.rb +0 -54
  77. data/lib/ccs/components/govuk/error_summary.rb +0 -70
  78. data/lib/ccs/components/govuk/field/input/character_count.rb +0 -129
  79. data/lib/ccs/components/govuk/field/input/file_upload.rb +0 -44
  80. data/lib/ccs/components/govuk/field/input/select.rb +0 -82
  81. data/lib/ccs/components/govuk/field/input/text_input/fix.rb +0 -55
  82. data/lib/ccs/components/govuk/field/input/text_input.rb +0 -97
  83. data/lib/ccs/components/govuk/field/input/textarea.rb +0 -59
  84. data/lib/ccs/components/govuk/field/input.rb +0 -62
  85. data/lib/ccs/components/govuk/field/inputs/checkboxes.rb +0 -69
  86. data/lib/ccs/components/govuk/field/inputs/date_input/item.rb +0 -65
  87. data/lib/ccs/components/govuk/field/inputs/date_input.rb +0 -89
  88. data/lib/ccs/components/govuk/field/inputs/item/checkbox/form.rb +0 -47
  89. data/lib/ccs/components/govuk/field/inputs/item/checkbox/tag.rb +0 -43
  90. data/lib/ccs/components/govuk/field/inputs/item/checkbox.rb +0 -50
  91. data/lib/ccs/components/govuk/field/inputs/item/divider.rb +0 -50
  92. data/lib/ccs/components/govuk/field/inputs/item/radio/form.rb +0 -44
  93. data/lib/ccs/components/govuk/field/inputs/item/radio/tag.rb +0 -43
  94. data/lib/ccs/components/govuk/field/inputs/item/radio.rb +0 -50
  95. data/lib/ccs/components/govuk/field/inputs/item.rb +0 -111
  96. data/lib/ccs/components/govuk/field/inputs/radios.rb +0 -69
  97. data/lib/ccs/components/govuk/field/inputs.rb +0 -57
  98. data/lib/ccs/components/govuk/field.rb +0 -108
  99. data/lib/ccs/components/govuk/fieldset/legend.rb +0 -65
  100. data/lib/ccs/components/govuk/fieldset.rb +0 -54
  101. data/lib/ccs/components/govuk/footer/link.rb +0 -55
  102. data/lib/ccs/components/govuk/footer/meta.rb +0 -59
  103. data/lib/ccs/components/govuk/footer/navigation.rb +0 -60
  104. data/lib/ccs/components/govuk/footer.rb +0 -131
  105. data/lib/ccs/components/govuk/form_group.rb +0 -60
  106. data/lib/ccs/components/govuk/header/link.rb +0 -56
  107. data/lib/ccs/components/govuk/header/navigation.rb +0 -71
  108. data/lib/ccs/components/govuk/header.rb +0 -107
  109. data/lib/ccs/components/govuk/hint.rb +0 -49
  110. data/lib/ccs/components/govuk/inset_text.rb +0 -52
  111. data/lib/ccs/components/govuk/label.rb +0 -85
  112. data/lib/ccs/components/govuk/notification_banner.rb +0 -107
  113. data/lib/ccs/components/govuk/pagination/increment/next.rb +0 -44
  114. data/lib/ccs/components/govuk/pagination/increment/previous.rb +0 -43
  115. data/lib/ccs/components/govuk/pagination/increment.rb +0 -98
  116. data/lib/ccs/components/govuk/pagination/item/ellipsis.rb +0 -28
  117. data/lib/ccs/components/govuk/pagination/item/form.rb +0 -49
  118. data/lib/ccs/components/govuk/pagination/item/tag.rb +0 -47
  119. data/lib/ccs/components/govuk/pagination/item.rb +0 -64
  120. data/lib/ccs/components/govuk/pagination.rb +0 -96
  121. data/lib/ccs/components/govuk/panel.rb +0 -62
  122. data/lib/ccs/components/govuk/phase_banner.rb +0 -69
  123. data/lib/ccs/components/govuk/skip_link.rb +0 -51
  124. data/lib/ccs/components/govuk/step_by_step_navigation/section/content/list/item.rb +0 -53
  125. data/lib/ccs/components/govuk/step_by_step_navigation/section/content/list.rb +0 -50
  126. data/lib/ccs/components/govuk/step_by_step_navigation/section/content/paragraph.rb +0 -45
  127. data/lib/ccs/components/govuk/step_by_step_navigation/section/content.rb +0 -63
  128. data/lib/ccs/components/govuk/step_by_step_navigation/section/heading.rb +0 -69
  129. data/lib/ccs/components/govuk/step_by_step_navigation/section.rb +0 -56
  130. data/lib/ccs/components/govuk/step_by_step_navigation.rb +0 -59
  131. data/lib/ccs/components/govuk/summary_list/action/link.rb +0 -59
  132. data/lib/ccs/components/govuk/summary_list/card/actions.rb +0 -59
  133. data/lib/ccs/components/govuk/summary_list/card/title.rb +0 -51
  134. data/lib/ccs/components/govuk/summary_list/card.rb +0 -63
  135. data/lib/ccs/components/govuk/summary_list/row/actions.rb +0 -59
  136. data/lib/ccs/components/govuk/summary_list/row/key.rb +0 -47
  137. data/lib/ccs/components/govuk/summary_list/row/value.rb +0 -47
  138. data/lib/ccs/components/govuk/summary_list/row.rb +0 -67
  139. data/lib/ccs/components/govuk/summary_list.rb +0 -74
  140. data/lib/ccs/components/govuk/table/body/data_cell.rb +0 -53
  141. data/lib/ccs/components/govuk/table/body/head_cell.rb +0 -52
  142. data/lib/ccs/components/govuk/table/header/head_cell.rb +0 -54
  143. data/lib/ccs/components/govuk/table.rb +0 -111
  144. data/lib/ccs/components/govuk/tabs/panel.rb +0 -58
  145. data/lib/ccs/components/govuk/tabs/tab.rb +0 -56
  146. data/lib/ccs/components/govuk/tabs.rb +0 -66
  147. data/lib/ccs/components/govuk/tag.rb +0 -51
  148. data/lib/ccs/components/govuk/warning_text.rb +0 -61
  149. data/lib/ccs/frontend_helpers/ccs_frontend/dashboard_section.rb +0 -27
  150. data/lib/ccs/frontend_helpers/govuk_frontend/character_count.rb +0 -28
  151. data/lib/ccs/frontend_helpers/govuk_frontend/checkboxes.rb +0 -28
  152. data/lib/ccs/frontend_helpers/govuk_frontend/date_input.rb +0 -28
  153. data/lib/ccs/frontend_helpers/govuk_frontend/file_upload.rb +0 -28
  154. data/lib/ccs/frontend_helpers/govuk_frontend/input.rb +0 -28
  155. data/lib/ccs/frontend_helpers/govuk_frontend/radios.rb +0 -28
  156. data/lib/ccs/frontend_helpers/govuk_frontend/select.rb +0 -28
  157. data/lib/ccs/frontend_helpers/govuk_frontend/textarea.rb +0 -28
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../field'
4
+
5
+ module CCS
6
+ module FrontendHelpers
7
+ module GovUKFrontend
8
+ module Field
9
+ # = GOV.UK Radios
10
+ #
11
+ # This helper is used for generating the radios component from the
12
+ # {https://design-system.service.gov.uk/components/radios GDS - Components - Radios}
13
+ #
14
+ # This is considered a Field module and so makes use of the methods in {CCS::FrontendHelpers::GovUKFrontend::Field}
15
+
16
+ module Radios
17
+ include Field
18
+
19
+ # Generates the HTML for the GOV.UK Radios component
20
+ #
21
+ # @param attribute [String, Symbol] the attribute of the raido buttons
22
+ # @param items [Array] array of radio items, see {_govuk_radios_fields}
23
+ # @param govuk_radios_options [Hash] options that will be used for the parts of the fieldset, form group, hint and radio buttons
24
+ #
25
+ # @option govuk_radios_options [String] :error_message (nil) the error message to be displayed
26
+ # @option govuk_radios_options [ActiveModel] :model (nil) optional model that can be used to find an error message
27
+ # @option govuk_radios_options [ActionView::Helpers::FormBuilder] :form (nil) optional form builder used to create
28
+ # the radio tags and find the error message
29
+ # @option govuk_radios_options [Hash] :form_group see {govuk_fields}
30
+ # @option govuk_radios_options [Hash] :fieldset see {govuk_fields}
31
+ # @option govuk_radios_options [Hash] :hint see {govuk_field}
32
+ # @option govuk_radios_options [Hash] :radios ({}) the options that will be used when rendering the radio buttons.
33
+ # See {govuk_radio_fields_tag} for more details.
34
+ #
35
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Radios
36
+ # which can then be rendered on the page
37
+
38
+ def govuk_radios(attribute, items, **govuk_radios_options)
39
+ govuk_fields(:radios, attribute, **govuk_radios_options) do |govuk_field_options|
40
+ if govuk_radios_options[:model] || govuk_radios_options[:form]
41
+ value = (govuk_radios_options[:model] || govuk_radios_options[:form].object).send(attribute)
42
+ items.each { |item| item[:checked] = item[:value] == value }
43
+ end
44
+
45
+ concat(
46
+ if govuk_radios_options[:form]
47
+ govuk_radio_fields_form(govuk_radios_options[:form], attribute, items, **govuk_field_options)
48
+ else
49
+ govuk_radio_fields_tag(attribute, items, **govuk_field_options)
50
+ end
51
+ )
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ # Generates the radios HTML for {govuk_radios}
58
+ #
59
+ # @param attribute [String, Symbol] the attribute of the raido buttons
60
+ # @param items [Array] array of radio items, see {_govuk_radios_fields}
61
+ # @param govuk_radios_options [Hash] options that will be used in customising the HTML
62
+ #
63
+ # @option (see _govuk_radios_fields)
64
+ #
65
+ # @return [ActiveSupport::SafeBuffer] the HTML for the radio buttons which is used in {govuk_radios}
66
+
67
+ def govuk_radio_fields_tag(attribute, items, **govuk_radios_options)
68
+ _govuk_radios_fields(items, **govuk_radios_options) do |radio_item|
69
+ govuk_radio_item_tag(attribute, radio_item)
70
+ end
71
+ end
72
+
73
+ # Generates the radios HTML for {govuk_radios} when there is a ActionView::Helpers::FormBuilder
74
+ #
75
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the radio buttons
76
+ # @param (see govuk_radio_fields_tag)
77
+ #
78
+ # @option (see _govuk_radios_fields)
79
+ #
80
+ # @return (see govuk_radio_fields_tag)
81
+
82
+ def govuk_radio_fields_form(form, attribute, items, **govuk_radios_options)
83
+ _govuk_radios_fields(items, **govuk_radios_options) do |radio_item|
84
+ govuk_radio_item_form(form, attribute, radio_item)
85
+ end
86
+ end
87
+
88
+ # Wrapper method used by {govuk_radio_fields_tag} and {govuk_radio_fields_form} to generate the radios HTML
89
+ #
90
+ # @param items [Array] array of radio items.
91
+ # Each item is a hash which can be:
92
+ # - +:divider+ text to separate radio items
93
+ # - radio item, see {_govuk_radio_item}
94
+ # @param govuk_radios_options [Hash] options that will be used in customising the HTML
95
+ #
96
+ # @option govuk_radios_options [String] :classes additional CSS classes for the radios HTML
97
+ # @option govuk_radios_options [Hash] :attributes ({ module: 'govuk-radios' }) any additional attributes that will added as part of the HTML
98
+ #
99
+ # @yield the radio item HTML generated by {govuk_radio_fields_tag} or {govuk_radio_fields_form}
100
+ #
101
+ # @yieldparam radio_item [Hash] the current radio item to be rendered
102
+ #
103
+ # @return [ActiveSupport::SafeBuffer] the HTML for the radio buttons which is used in {govuk_radio_fields_tag} or {govuk_radio_fields_form}
104
+
105
+ def _govuk_radios_fields(items, **govuk_radios_options)
106
+ initialise_attributes_and_set_classes(govuk_radios_options, 'govuk-radios')
107
+ set_data_module(govuk_radios_options, 'govuk-radios')
108
+
109
+ tag.div(**govuk_radios_options[:attributes]) do
110
+ items.each do |radio_item|
111
+ concat(
112
+ if radio_item[:divider]
113
+ tag.div(radio_item[:divider], class: 'govuk-radios__divider')
114
+ else
115
+ tag.div(class: 'govuk-radios__item') do
116
+ yield(radio_item)
117
+ end
118
+ end
119
+ )
120
+ end
121
+ end
122
+ end
123
+
124
+ # Generates the HTML for a radio button for {govuk_radio_fields_form}
125
+ #
126
+ # @param (see _govuk_radio_item)
127
+ #
128
+ # @option (see _govuk_radio_item)
129
+ #
130
+ # @return (see _govuk_radio_item)
131
+
132
+ def govuk_radio_item_tag(attribute, radio_item)
133
+ _govuk_radio_item(attribute, radio_item) do
134
+ label_attribute = radio_item[:attributes][:id] || "#{attribute}[#{radio_item[:value]}]"
135
+
136
+ concat(radio_button_tag(attribute, radio_item[:value], radio_item[:checked], **radio_item[:attributes]))
137
+ concat(govuk_label(label_attribute, radio_item[:label][:text], **radio_item[:label]))
138
+ end
139
+ end
140
+
141
+ # Generates the HTML for a radio button for {govuk_radio_fields_tag}
142
+ #
143
+ # @param (see _govuk_radio_item)
144
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the radio buttons
145
+ #
146
+ # @option (see _govuk_radio_item)
147
+ #
148
+ # @return (see _govuk_radio_item)
149
+
150
+ def govuk_radio_item_form(form, attribute, radio_item)
151
+ _govuk_radio_item(attribute, radio_item) do
152
+ (radio_item[:label][:attributes] ||= {})[:value] = radio_item[:value]
153
+ radio_item[:label][:attributes][:for] = radio_item[:attributes][:id] if radio_item[:attributes][:id]
154
+
155
+ concat(form.radio_button(attribute, radio_item[:value], **radio_item[:attributes]))
156
+ concat(govuk_label(attribute, radio_item[:label][:text], form: form, **radio_item[:label]))
157
+ end
158
+ end
159
+
160
+ # rubocop:disable Metrics/AbcSize
161
+
162
+ # Wrapper method used by {govuk_radio_item_tag} and {govuk_radio_item_form} to generate the radios HTML
163
+ # including the label and hint, if there is one.
164
+ #
165
+ # @param attribute [String, Symbol] the attribute of the raido buttons
166
+ # @param radio_item [Hash] the options for the radio item
167
+ #
168
+ # @option radio_item [String] :classes additional CSS classes for the radio button HTML
169
+ # @option radio_item [Hash] :label the parameters that will be used to create the label for the radio button, see {govuk_label}
170
+ # @option radio_item [Hash] :hint (nil) the parameters that will be used to create the hint for the radio button, see {govuk_hint}.
171
+ # If no hint is given then no hint will be rendered
172
+ # @option radio_item [Hash] :conditional (nil) content that will appear when the radio button is checked.
173
+ # It can have the following options:
174
+ # - +[:content]+ the content that will be shown
175
+ # - +[:attributes][:id]+ the id of the conditional section
176
+ # If no conditional is given then no conditional content will be rendered
177
+ # @option radio_item [Hash] :attributes ({}) any additional attributes that will be added as part of the radio button HTML
178
+ #
179
+ # @return [ActiveSupport::SafeBuffer] the HTML for the radio buttons, label and hint
180
+ # which is used in {govuk_radio_item_tag} and {govuk_radio_item_form}
181
+
182
+ def _govuk_radio_item(attribute, radio_item)
183
+ (radio_item[:attributes] ||= {})[:class] = 'govuk-radios__input'
184
+
185
+ radio_item[:label] ||= {}
186
+ radio_item[:label][:classes] = "govuk-radios__label #{radio_item[:label][:classes]}".rstrip
187
+
188
+ set_item_options_for_hint('radios', attribute, radio_item)
189
+ set_conditional_item_options('radios', attribute, radio_item)
190
+
191
+ yield
192
+ concat(govuk_hint(radio_item[:hint][:text], **radio_item[:hint])) if radio_item[:hint]
193
+ concat(tag.div(radio_item[:conditional][:content], class: radio_item[:conditional][:attributes][:class], id: radio_item[:conditional][:attributes][:id])) if radio_item[:conditional]
194
+ end
195
+
196
+ # rubocop:enable Metrics/AbcSize
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+ require_relative '../field'
5
+
6
+ module CCS
7
+ module FrontendHelpers
8
+ module GovUKFrontend
9
+ module Field
10
+ # = GOV.UK Select
11
+ #
12
+ # This helper is used for generating the select component from the
13
+ # {https://design-system.service.gov.uk/components/select GDS - Components - Select}
14
+ #
15
+ # This is considered a Field module and so makes use of the methods in {CCS::FrontendHelpers::GovUKFrontend::Field}
16
+
17
+ module Select
18
+ include ActionView::Helpers::FormOptionsHelper
19
+ include Field
20
+
21
+ # Generates the HTML for the GOV.UK Select component
22
+ #
23
+ # @param attribute [String, Symbol] the attribute of the select field
24
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
25
+ # @param govuk_select_options [Hash] options that will be used for the parts of the form group, label, hint and select
26
+ #
27
+ # @option govuk_select_options [String] :error_message (nil) the error message to be displayed
28
+ # @option govuk_select_options [ActiveModel] :model (nil) optional model that can be used to find an error message
29
+ # @option govuk_select_options [ActionView::Helpers::FormBuilder] :form (nil) optional form builder used to create
30
+ # the select tag and find the error message
31
+ # @option govuk_select_options [Hash] :form_group see {govuk_field}
32
+ # @option govuk_select_options [Hash] :label see {govuk_field}
33
+ # @option govuk_select_options [Hash] :hint see {govuk_field}
34
+ # @option govuk_select_options [Hash] :select ({}) the options that will be used when rendering the select field.
35
+ # See {govuk_select_tag} for more details.
36
+ #
37
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Select
38
+ # which can then be rendered on the page
39
+
40
+ def govuk_select(attribute, items, **govuk_select_options)
41
+ govuk_field(:select, attribute, **govuk_select_options) do |govuk_field_options, error_message|
42
+ initialise_attributes_and_set_classes(govuk_field_options, "govuk-select #{'govuk-select--error' if error_message}".rstrip)
43
+
44
+ (govuk_select_options[:select] ||= {})[:selected] = govuk_select_options[:model].send(attribute) if govuk_select_options[:model]
45
+
46
+ concat(
47
+ if govuk_select_options[:form]
48
+ govuk_select_form(govuk_select_options[:form], attribute, items, **govuk_field_options)
49
+ else
50
+ govuk_select_tag(attribute, items, **govuk_field_options)
51
+ end
52
+ )
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ # Generates the select HTML for {govuk_select}
59
+ #
60
+ # @param attribute [String, Symbol] the attribute of the select field
61
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
62
+ # @param govuk_select_options [Hash] options that will be used in customising the HTML
63
+ #
64
+ # @option govuk_select_options [String] :classes additional CSS classes for the select HTML
65
+ # @option govuk_select_options [String] :selected (nil) the selected option
66
+ # @option govuk_select_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
67
+ #
68
+ # @return [ActiveSupport::SafeBuffer] the HTML for the select field which is used in {govuk_select}
69
+
70
+ def govuk_select_tag(attribute, items, **govuk_select_options)
71
+ select_tag(
72
+ attribute,
73
+ options_for_select(
74
+ govuk_map_select_items(items),
75
+ govuk_select_options[:selected]
76
+ ),
77
+ **govuk_select_options[:attributes]
78
+ )
79
+ end
80
+
81
+ # Generates the select HTML for {govuk_select} when there is a ActionView::Helpers::FormBuilder
82
+ #
83
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the select field
84
+ # @param (see govuk_select_tag)
85
+ #
86
+ # @option (see govuk_select_tag)
87
+ #
88
+ # @return (see govuk_select_tag)
89
+
90
+ def govuk_select_form(form, attribute, items, **govuk_select_options)
91
+ form.select(
92
+ attribute,
93
+ govuk_map_select_items(items),
94
+ govuk_select_options[:select_options] || {},
95
+ **govuk_select_options[:attributes]
96
+ )
97
+ end
98
+
99
+ # Maps the items into an array that can be used to generate the options for
100
+ # {govuk_select_tag} and {govuk_select_form}
101
+ #
102
+ # @param items [Array] array of option items for the select
103
+ #
104
+ # @option items [String] :text the text of the option item.
105
+ # If this is blank the value is used
106
+ # @option items [String] :value the value of the option item
107
+ # @option items [Hash] :attributes ({}) any additional attributes that will added as part of the option HTML
108
+ #
109
+ # @return [Array] array of option params that are used in {govuk_select_tag} and {govuk_select_form}
110
+
111
+ def govuk_map_select_items(items)
112
+ items.map do |item|
113
+ [
114
+ item[:text] || item[:value],
115
+ item[:value],
116
+ (item[:attributes] || {})
117
+ ]
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../field'
4
+
5
+ module CCS
6
+ module FrontendHelpers
7
+ module GovUKFrontend
8
+ module Field
9
+ # = GOV.UK Textarea
10
+ #
11
+ # This helper is used for generating the textarea component from the
12
+ # {https://design-system.service.gov.uk/components/textarea GDS - Components - Textarea}
13
+ #
14
+ # This is considered a Field module and so makes use of the methods in {CCS::FrontendHelpers::GovUKFrontend::Field}
15
+
16
+ module Textarea
17
+ include Field
18
+
19
+ # Generates the HTML for the GOV.UK textarea component
20
+ #
21
+ # @param attribute [String, Symbol] the attribute of the textarea
22
+ # @param govuk_textarea_options [Hash] options that will be used for the parts of the form group, label, hint and textarea
23
+ #
24
+ # @option govuk_textarea_options [String] :error_message (nil) the error message to be displayed
25
+ # @option govuk_textarea_options [ActiveModel] :model (nil) optional model that can be used to find an error message
26
+ # @option govuk_textarea_options [ActionView::Helpers::FormBuilder] :form (nil) optional form builder used to create
27
+ # the textarea tag and find the error message
28
+ # @option govuk_textarea_options [Hash] :form_group see {govuk_field}
29
+ # @option govuk_textarea_options [Hash] :label see {govuk_field}
30
+ # @option govuk_textarea_options [Hash] :hint see {govuk_field}
31
+ # @option govuk_textarea_options [Hash] :textarea ({}) the options that will be used when rendering the textarea.
32
+ # See {set_govuk_textarea_field_options} for more details.
33
+ #
34
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK textarea
35
+ # which can then be rendered on the page
36
+
37
+ def govuk_textarea(attribute, **govuk_textarea_options)
38
+ govuk_field(:textarea, attribute, **govuk_textarea_options) do |govuk_field_options, error_message|
39
+ set_govuk_textarea_field_options(error_message, govuk_field_options)
40
+ (govuk_textarea_options[:textarea] ||= {})[:content] = govuk_textarea_options[:model].send(attribute) if govuk_textarea_options[:model]
41
+
42
+ concat(
43
+ if govuk_textarea_options[:form]
44
+ govuk_textarea_form(govuk_textarea_options[:form], attribute, **govuk_field_options)
45
+ else
46
+ govuk_textarea_tag(attribute, **govuk_field_options)
47
+ end
48
+ )
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ # Generates the textarea HTML for {govuk_textarea}
55
+ #
56
+ # @param attribute [String, Symbol] the attribute of the textarea
57
+ # @param govuk_text_textarea_options [Hash] options that will be used in customising the HTML
58
+ #
59
+ # @option (see set_govuk_textarea_field_options)
60
+ #
61
+ # @return [ActiveSupport::SafeBuffer] the HTML for the textarea field which is used in {govuk_textarea}
62
+
63
+ def govuk_textarea_tag(attribute, **govuk_text_textarea_options)
64
+ text_area_tag(
65
+ attribute,
66
+ govuk_text_textarea_options[:content],
67
+ **govuk_text_textarea_options[:attributes]
68
+ )
69
+ end
70
+
71
+ # Generates the textarea HTML for {govuk_textarea} when there is a ActionView::Helpers::FormBuilder
72
+ #
73
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the textarea
74
+ # @param (see govuk_textarea_tag)
75
+ #
76
+ # @option (see set_govuk_textarea_field_options)
77
+ #
78
+ # @return (see govuk_textarea_tag)
79
+
80
+ def govuk_textarea_form(form, attribute, **govuk_text_textarea_options)
81
+ form.text_area(
82
+ attribute,
83
+ **govuk_text_textarea_options[:attributes]
84
+ )
85
+ end
86
+
87
+ # Initialises the attributes for the textarea input
88
+ #
89
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
90
+ # @param govuk_text_textarea_options [Hash] options that will be used in customising the HTML
91
+ #
92
+ # @option govuk_text_textarea_options [String] :classes additional CSS classes for the textarea HTML
93
+ # @option govuk_text_textarea_options [String] :content (nil) the content of the textarea
94
+ # @option govuk_text_textarea_options [String] :rows (5) the number of rows for the text area
95
+ # @option govuk_text_textarea_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
96
+
97
+ def set_govuk_textarea_field_options(error_message, govuk_text_textarea_options)
98
+ initialise_attributes_and_set_classes(govuk_text_textarea_options, "govuk-textarea #{'govuk-textarea--error' if error_message}".rstrip)
99
+
100
+ govuk_text_textarea_options[:attributes][:rows] ||= govuk_text_textarea_options[:rows] || 5
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -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