crown_marketplace_utils 0.1.0.beta.2 → 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.
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+ require_relative '../field'
5
+
6
+ module CrownMarketplaceUtils
7
+ module GovUkHelper
8
+ module Field
9
+ # = GOV.UK Select
10
+ #
11
+ # This helper is used for generating the select component from the
12
+ # {https://design-system.service.gov.uk/components/select GDS - Components - Select}
13
+ #
14
+ # This is considered a Field module and so makes use of the methods in {CrownMarketplaceUtils::GovUkHelper::Field}
15
+
16
+ module Select
17
+ include ActionView::Helpers::FormOptionsHelper
18
+ include Field
19
+
20
+ # Generates the HTML for the GOV.UK Select component
21
+ #
22
+ # @param attribute [String, Symbol] the attribute of the select field
23
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
24
+ # @param error_message [String] the error message to be displayed
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 [Hash] :form_group_options see {govuk_field}
28
+ # @option govuk_select_options [Hash] :label see {govuk_field}
29
+ # @option govuk_select_options [Hash] :hint see {govuk_field}
30
+ # @option govuk_select_options [Hash] :select_options ({}) the options that will be used when rendering the select field.
31
+ # See {govuk_select_field} for more details.
32
+ #
33
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Select
34
+ # which can then be rendered on the page
35
+
36
+ def govuk_select(attribute, items, error_message = nil, **govuk_select_options)
37
+ govuk_field(:select, attribute, error_message, **govuk_select_options) do |govuk_field_options|
38
+ concat(govuk_select_field(attribute, items, error_message, **govuk_field_options))
39
+ end
40
+ end
41
+
42
+ # Generates the HTML for the GOV.UK Select component using an ActionView::Helpers::FormBuilder.
43
+ # Unlike {govuk_select}, the method will be able to automatically determine if the error message needs to be shown.
44
+ #
45
+ # @param form [ActionView::Helpers::FormBuilder] :form the form builder used to create the select field
46
+ # @param attribute [String, Symbol] the attribute of the select field
47
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
48
+ # @param govuk_select_options [Hash] options that will be used for the parts of the form group, label, hint and select
49
+ #
50
+ # @option govuk_select_options [Hash] :form_group_options see {govuk_field_with_form}
51
+ # @option govuk_select_options [Hash] :label see {govuk_field_with_form}
52
+ # @option govuk_select_options [Hash] :hint see {govuk_field_with_form}
53
+ # @option govuk_select_options [Hash] :select_options ({}) the options that will be used when rendering the select field.
54
+ # See {govuk_select_field_with_form} for more details.
55
+ #
56
+ # @return (see govuk_select)
57
+
58
+ def govuk_select_with_form(form, attribute, items, **govuk_select_options)
59
+ govuk_field_with_form(:select, form, attribute, **govuk_select_options) do |govuk_field_options, error_message|
60
+ concat(govuk_select_field_with_form(form, attribute, items, error_message, **govuk_field_options))
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ # Generates the select HTML for {govuk_select}
67
+ #
68
+ # @param attribute [String, Symbol] the attribute of the select field
69
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
70
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
71
+ # @param govuk_select_options [Hash] options that will be used in customising the HTML
72
+ #
73
+ # @option (see _govuk_select_field)
74
+ #
75
+ # @return [ActiveSupport::SafeBuffer] the HTML for the select field which is used in {govuk_select}
76
+
77
+ def govuk_select_field(attribute, items, error_message, **govuk_select_options)
78
+ _govuk_select_field(error_message, **govuk_select_options) do |govuk_select_classes, govuk_select_attributes|
79
+ select_tag(
80
+ attribute,
81
+ options_for_select(
82
+ govuk_map_select_items(items),
83
+ govuk_select_options[:selected]
84
+ ),
85
+ class: govuk_select_classes,
86
+ **govuk_select_attributes
87
+ )
88
+ end
89
+ end
90
+
91
+ # Generates the select HTML for {govuk_select_with_form}
92
+ #
93
+ # @param form [ActionView::Helpers::FormBuilder] :form the form builder used to create the select field
94
+ # @param attribute [String, Symbol] the attribute of the select field
95
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
96
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
97
+ # @param govuk_select_options [Hash] options that will be used in customising the HTML
98
+ #
99
+ # @option (see _govuk_select_field)
100
+ #
101
+ # @return [ActiveSupport::SafeBuffer] the HTML for the select field which is used in {govuk_select_with_form}
102
+
103
+ def govuk_select_field_with_form(form, attribute, items, error_message, **govuk_select_options)
104
+ _govuk_select_field(error_message, **govuk_select_options) do |govuk_select_classes, govuk_select_attributes|
105
+ form.select(
106
+ attribute,
107
+ govuk_map_select_items(items),
108
+ govuk_select_options[:select_options] || {},
109
+ class: govuk_select_classes,
110
+ **govuk_select_attributes
111
+ )
112
+ end
113
+ end
114
+
115
+ # Wrapper method used by {govuk_select_field} and {govuk_select_field_with_form} to generate the select HTML
116
+ #
117
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
118
+ # @param govuk_select_options [Hash] options that will be used in customising the HTML
119
+ #
120
+ # @option govuk_select_options [String] :classes additional CSS classes for the select HTML
121
+ # @option govuk_select_options [String] :selected (nil) the selected option
122
+ # @option govuk_select_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
123
+ #
124
+ # @yield the select HTML generated by {govuk_select_field} or {govuk_select_field_with_form}
125
+ #
126
+ # @yieldparam govuk_select_classes [Array] the classes for the select HTML
127
+ # @yieldparam govuk_select_attributes [Hash] additional attributes that will added as part of the HTML
128
+ #
129
+ # @return [ActiveSupport::SafeBuffer] the HTML for the select field which is used in {govuk_select_field} or {govuk_select_field_with_form}
130
+
131
+ def _govuk_select_field(error_message, **govuk_select_options)
132
+ govuk_select_classes = ['govuk-select']
133
+ govuk_select_classes += ['govuk-select--error'] if error_message
134
+ govuk_select_classes << govuk_select_options[:classes]
135
+ govuk_select_options[:attributes] ||= {}
136
+
137
+ yield(govuk_select_classes, govuk_select_options[:attributes])
138
+ end
139
+
140
+ # Maps the items into an array that can be used to generate the options for
141
+ # {govuk_select_field} and {govuk_select_field_with_form}
142
+ #
143
+ # @param items [Array] array of option items for the select
144
+ #
145
+ # @option items [String] :text the text of the option item.
146
+ # If this is blank the value is used
147
+ # @option items [String] :value the value of the option item
148
+ # @option items [Hash] :attributes ({}) any additional attributes that will added as part of the option HTML
149
+ #
150
+ # @return [Array] array of option params that are used in {govuk_select_field} and {govuk_select_field_with_form}
151
+
152
+ def govuk_map_select_items(items)
153
+ items.map do |item|
154
+ [
155
+ item[:text] || item[:value],
156
+ item[:value],
157
+ (item[:attributes] || {})
158
+ ]
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ ActionView::Base.field_error_proc = proc { |html_tag, _instance| html_tag }
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../field'
4
+
5
+ module CrownMarketplaceUtils
6
+ module GovUkHelper
7
+ module Field
8
+ # = GOV.UK Textarea
9
+ #
10
+ # This helper is used for generating the textarea component from the
11
+ # {https://design-system.service.gov.uk/components/textarea GDS - Components - Textarea}
12
+ #
13
+ # This is considered a Field module and so makes use of the methods in {CrownMarketplaceUtils::GovUkHelper::Field}
14
+
15
+ module Textarea
16
+ include Field
17
+
18
+ # Generates the HTML for the GOV.UK textarea component
19
+ #
20
+ # @param attribute [String, Symbol] the attribute of the textarea
21
+ # @param error_message [String] the error message to be displayed
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 [Hash] :form_group_options see {govuk_field}
25
+ # @option govuk_textarea_options [Hash] :label see {govuk_field}
26
+ # @option govuk_textarea_options [Hash] :hint see {govuk_field}
27
+ # @option govuk_textarea_options [Hash] :textarea_options ({}) the options that will be used when rendering the textarea.
28
+ # See {govuk_textarea_field} for more details.
29
+ #
30
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK textarea
31
+ # which can then be rendered on the page
32
+
33
+ def govuk_textarea(attribute, error_message = nil, **govuk_textarea_options)
34
+ govuk_field(:textarea, attribute, error_message, **govuk_textarea_options) do |govuk_field_options|
35
+ concat(govuk_textarea_field(attribute, error_message, **govuk_field_options))
36
+ end
37
+ end
38
+
39
+ # Generates the HTML for the GOV.UK textarea component using an ActionView::Helpers::FormBuilder.
40
+ # Unlike {#govuk_textarea}, the method will be able to automatically determine if the error message needs to be shown.
41
+ #
42
+ # @param form [ActionView::Helpers::FormBuilder] :form the form builder used to create the textarea
43
+ # @param attribute [String, Symbol] the attribute of the textarea
44
+ # @param govuk_textarea_options [Hash] options that will be used for the parts of the form group, label, hint and textarea
45
+ #
46
+ # @option govuk_textarea_options [Hash] :form_group_options see {govuk_field_with_form}
47
+ # @option govuk_textarea_options [Hash] :label see {govuk_field_with_form}
48
+ # @option govuk_textarea_options [Hash] :hint see {govuk_field_with_form}
49
+ # @option govuk_textarea_options [Hash] :textarea_options ({}) the options that will be used when rendering the textarea.
50
+ # See {govuk_textarea_field_with_form} for more details.
51
+ #
52
+ # @return (see govuk_textarea)
53
+
54
+ def govuk_textarea_with_form(form, attribute, **govuk_textarea_options)
55
+ govuk_field_with_form(:textarea, form, attribute, **govuk_textarea_options) do |govuk_field_options, error_message|
56
+ concat(govuk_textarea_field_with_form(form, attribute, error_message, **govuk_field_options))
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ # Generates the textarea HTML for {govuk_textarea}
63
+ #
64
+ # @param attribute [String, Symbol] the attribute of the textarea
65
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
66
+ # @param govuk_text_textarea_options [Hash] options that will be used in customising the HTML
67
+ #
68
+ # @option (see _govuk_textarea_field)
69
+ #
70
+ # @return [ActiveSupport::SafeBuffer] the HTML for the textarea field which is used in {govuk_textarea}
71
+
72
+ def govuk_textarea_field(attribute, error_message, **govuk_text_textarea_options)
73
+ _govuk_textarea_field(error_message, **govuk_text_textarea_options) do |govuk_text_textarea_classes, govuk_text_textarea_rows, govuk_text_textarea_attributes|
74
+ text_area_tag(attribute, govuk_text_textarea_options[:content], class: govuk_text_textarea_classes, rows: govuk_text_textarea_rows, **govuk_text_textarea_attributes)
75
+ end
76
+ end
77
+
78
+ # Generates the textarea HTML for {govuk_textarea_with_form}
79
+ #
80
+ # @param form [ActionView::Helpers::FormBuilder] :form the form builder used to create the textarea
81
+ # @param attribute [String, Symbol] the attribute of the textarea
82
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
83
+ # @param govuk_text_textarea_options [Hash] options that will be used in customising the HTML
84
+ #
85
+ # @option (see _govuk_textarea_field)
86
+ #
87
+ # @return [ActiveSupport::SafeBuffer] the HTML for the textarea field which is used in {govuk_textarea_with_form}
88
+
89
+ def govuk_textarea_field_with_form(form, attribute, error_message, **govuk_text_textarea_options)
90
+ _govuk_textarea_field(error_message, **govuk_text_textarea_options) do |govuk_text_textarea_classes, govuk_text_textarea_rows, govuk_text_textarea_attributes|
91
+ form.text_area(attribute, class: govuk_text_textarea_classes, rows: govuk_text_textarea_rows, **govuk_text_textarea_attributes)
92
+ end
93
+ end
94
+
95
+ # Wrapper method used by {govuk_textarea_field} and {govuk_textarea_field_with_form} to generate the textarea HTML
96
+ #
97
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
98
+ # @param govuk_text_textarea_options [Hash] options that will be used in customising the HTML
99
+ #
100
+ # @option govuk_text_textarea_options [String] :classes additional CSS classes for the textarea HTML
101
+ # @option govuk_text_textarea_options [String] :content (nil) the content of the textarea
102
+ # @option govuk_text_textarea_options [String] :rows (5) the number of rows for the text area
103
+ # @option govuk_text_textarea_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
104
+ #
105
+ # @yield the textarea HTML generated by {govuk_textarea_field} or {govuk_textarea_field_with_form}
106
+ #
107
+ # @yieldparam govuk_text_textarea_classes [Array] the classes for the label HTML
108
+ # @yieldparam govuk_text_textarea_rows [Integer, String] (5) the number of rows for the text area
109
+ # @yieldparam govuk_text_textarea_attributes [Hash] additional attributes that will added as part of the HTML
110
+ #
111
+ # @return [ActiveSupport::SafeBuffer] the HTML for the textarea field which is used in {govuk_textarea_field} or {govuk_textarea_field_with_form}
112
+
113
+ def _govuk_textarea_field(error_message, **govuk_text_textarea_options)
114
+ govuk_text_textarea_classes = ['govuk-textarea']
115
+ govuk_text_textarea_classes += ['govuk-textarea--error'] if error_message
116
+ govuk_text_textarea_classes << govuk_text_textarea_options[:classes]
117
+ govuk_text_textarea_options[:attributes] ||= {}
118
+ govuk_text_textarea_options[:rows] ||= 5
119
+
120
+ yield(govuk_text_textarea_classes, govuk_text_textarea_options[:rows], govuk_text_textarea_options[:attributes])
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ ActionView::Base.field_error_proc = proc { |html_tag, _instance| html_tag }
@@ -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
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'action_view'
4
3
  require_relative 'error_message'
5
4
 
6
5
  module CrownMarketplaceUtils
@@ -10,8 +9,6 @@ module CrownMarketplaceUtils
10
9
  # This helper is used for generating the form group component from the Government Design Systems
11
10
 
12
11
  module FormGroup
13
- include ActionView::Context
14
- include ActionView::Helpers::TagHelper
15
12
  include ErrorMessage
16
13
 
17
14
  # Generates the HTML for the GOV.UK Form Group component