ccs-frontend_helpers 0.1.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -3
- data/CHANGELOG.md +40 -0
- data/Gemfile +7 -6
- data/Gemfile.lock +121 -114
- data/README.md +12 -0
- data/lib/ccs/components/ccs/footer.rb +0 -1
- data/lib/ccs/components/ccs/header.rb +0 -1
- data/lib/ccs/components/govuk/accordion/section/content.rb +1 -1
- data/lib/ccs/components/govuk/accordion.rb +11 -0
- data/lib/ccs/components/govuk/button.rb +4 -1
- data/lib/ccs/components/govuk/cookie_banner/action.rb +1 -0
- data/lib/ccs/components/govuk/cookie_banner/message.rb +1 -1
- data/lib/ccs/components/govuk/details.rb +1 -1
- data/lib/ccs/components/govuk/error_message.rb +5 -2
- data/lib/ccs/components/govuk/exit_this_page.rb +79 -0
- data/lib/ccs/components/govuk/field/input/character_count/count_message.rb +62 -0
- data/lib/ccs/components/govuk/field/input/character_count.rb +55 -42
- data/lib/ccs/components/govuk/field/input/password_input/show_hide_button.rb +72 -0
- data/lib/ccs/components/govuk/field/input/password_input.rb +101 -0
- data/lib/ccs/components/govuk/field/input/select.rb +2 -2
- data/lib/ccs/components/govuk/field/input/text_input.rb +23 -7
- data/lib/ccs/components/govuk/field/input.rb +4 -0
- data/lib/ccs/components/govuk/field/inputs/checkboxes.rb +8 -28
- data/lib/ccs/components/govuk/field/inputs/date_input.rb +4 -25
- data/lib/ccs/components/govuk/field/inputs/item/checkbox.rb +1 -13
- data/lib/ccs/components/govuk/field/inputs/item/radio.rb +1 -13
- data/lib/ccs/components/govuk/field/inputs/item.rb +24 -10
- data/lib/ccs/components/govuk/field/inputs/radios.rb +7 -23
- data/lib/ccs/components/govuk/field/inputs.rb +31 -7
- data/lib/ccs/components/govuk/field.rb +12 -2
- data/lib/ccs/components/govuk/fieldset.rb +1 -1
- data/lib/ccs/components/govuk/footer/meta.rb +1 -1
- data/lib/ccs/components/govuk/footer.rb +1 -2
- data/lib/ccs/components/govuk/header/navigation.rb +4 -2
- data/lib/ccs/components/govuk/header.rb +26 -8
- data/lib/ccs/components/govuk/pagination/increment/next.rb +6 -3
- data/lib/ccs/components/govuk/pagination/increment/previous.rb +6 -3
- data/lib/ccs/components/govuk/pagination/increment.rb +11 -3
- data/lib/ccs/components/govuk/pagination/item.rb +1 -1
- data/lib/ccs/components/govuk/pagination.rb +2 -3
- data/lib/ccs/components/govuk/summary_list/action/link.rb +18 -3
- data/lib/ccs/components/govuk/summary_list/card/actions.rb +3 -2
- data/lib/ccs/components/govuk/summary_list/card.rb +1 -1
- data/lib/ccs/components/govuk/summary_list/row/actions.rb +3 -2
- data/lib/ccs/components/govuk/summary_list/row.rb +7 -2
- data/lib/ccs/components/govuk/summary_list.rb +1 -1
- data/lib/ccs/components/govuk/tabs.rb +5 -3
- data/lib/ccs/components/govuk/task_list/item/status.rb +64 -0
- data/lib/ccs/components/govuk/task_list/item/title.rb +54 -0
- data/lib/ccs/components/govuk/task_list/item.rb +75 -0
- data/lib/ccs/components/govuk/task_list.rb +52 -0
- data/lib/ccs/components/govuk/warning_text.rb +1 -1
- data/lib/ccs/frontend_helpers/govuk_frontend/character_count.rb +1 -1
- data/lib/ccs/frontend_helpers/govuk_frontend/error_message.rb +1 -1
- data/lib/ccs/frontend_helpers/govuk_frontend/exit_this_page.rb +28 -0
- data/lib/ccs/frontend_helpers/govuk_frontend/password_input.rb +28 -0
- data/lib/ccs/frontend_helpers/govuk_frontend/task_list.rb +28 -0
- data/lib/ccs/frontend_helpers/govuk_frontend.rb +6 -0
- data/lib/ccs/frontend_helpers/version.rb +1 -1
- data/package.json +10 -0
- data/yarn.lock +8 -0
- metadata +15 -2
@@ -0,0 +1,79 @@
|
|
1
|
+
require_relative '../base'
|
2
|
+
require_relative 'button'
|
3
|
+
|
4
|
+
module CCS
|
5
|
+
module Components
|
6
|
+
module GovUK
|
7
|
+
# = GOV.UK Exit this page
|
8
|
+
#
|
9
|
+
# This is used to generate the exit this page component from the
|
10
|
+
# {https://design-system.service.gov.uk/components/exit-this-page GDS - Components - Exit this page}
|
11
|
+
#
|
12
|
+
# @!attribute [r] text
|
13
|
+
# @return [String] Text for the exit this page
|
14
|
+
# @!attribute [r] redirect_url
|
15
|
+
# @return [String] The redirect_url for the exit this page
|
16
|
+
|
17
|
+
class ExitThisPage < Base
|
18
|
+
include ActionView::Context
|
19
|
+
include ActionView::Helpers
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :text, :redirect_url
|
24
|
+
|
25
|
+
public
|
26
|
+
|
27
|
+
# @param text [String] the text for the exit this page
|
28
|
+
# @param redirect_url [String] the href for the exit this page
|
29
|
+
# @param options [Hash] options that will be used in customising the HTML
|
30
|
+
#
|
31
|
+
# @option options [String] :classes additional CSS classes for the exit this page HTML
|
32
|
+
# @option options [String] :activated_text Text announced by screen readers when Exit this Page has been activated via the keyboard shortcut. Defaults to "Loading."
|
33
|
+
# @option options [String] :timed_out_text Text announced by screen readers when the keyboard shortcut has timed out without successful activation. Defaults to "Exit this page expired."
|
34
|
+
# @option options [String] :press_two_more_times_text Text announced by screen readers when the user must press Shift two more times to activate the button. Defaults to "Shift, press 2 more times to exit."
|
35
|
+
# @option options [String] :press_one_more_time_text Text announced by screen readers when the user must press Shift one more time to activate the button. Defaults to "Shift, press 1 more time to exit."
|
36
|
+
# @option options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
|
37
|
+
|
38
|
+
def initialize(text: nil, redirect_url: nil, **options)
|
39
|
+
super(**options)
|
40
|
+
|
41
|
+
@text = text || default_text
|
42
|
+
@redirect_url = redirect_url || 'https://www.bbc.co.uk/weather'
|
43
|
+
|
44
|
+
%i[activated timed_out press_two_more_times press_one_more_time].each do |data_attribute|
|
45
|
+
data_attribute_name = :"#{data_attribute}_text"
|
46
|
+
@options[:attributes][:data][:"i18n.#{data_attribute.to_s.gsub('_', '-')}"] = options[data_attribute_name] if options[data_attribute_name]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Generates the HTML for the GOV.UK Exit this page component
|
51
|
+
#
|
52
|
+
# @return [ActiveSupport::SafeBuffer]
|
53
|
+
|
54
|
+
def render
|
55
|
+
tag.div(**options[:attributes]) do
|
56
|
+
Button.new(text: text, href: redirect_url, context: context, classes: 'govuk-button--warning govuk-exit-this-page__button govuk-js-exit-this-page-button', attributes: { rel: 'nofollow noreferrer' }).render
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# The default attributes for the exit this page
|
61
|
+
|
62
|
+
DEFAULT_ATTRIBUTES = { class: 'govuk-exit-this-page', data: { module: 'govuk-exit-this-page' } }.freeze
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# Generates the default HTML for the GOV.UK exit this page component
|
67
|
+
#
|
68
|
+
# @return [ActiveSupport::SafeBuffer]
|
69
|
+
|
70
|
+
def default_text
|
71
|
+
capture do
|
72
|
+
concat(tag.span('Emergency', class: 'govuk-visually-hidden'))
|
73
|
+
concat(' Exit this page')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module CCS
|
2
|
+
module Components
|
3
|
+
module GovUK
|
4
|
+
class Field < Base
|
5
|
+
class Input < Field
|
6
|
+
class CharacterCount
|
7
|
+
# = GOV.UK Character count message
|
8
|
+
#
|
9
|
+
# This is used to generate the character count message
|
10
|
+
#
|
11
|
+
# @!attribute [r] count_message
|
12
|
+
# @return [Hint] Hint with the count message
|
13
|
+
# @!attribute [r] after_input
|
14
|
+
# @return [String] Text or HTML for after the textarea input
|
15
|
+
|
16
|
+
class CountMessage
|
17
|
+
include ActionView::Context
|
18
|
+
include ActionView::Helpers
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :count_message, :after_input
|
23
|
+
|
24
|
+
public
|
25
|
+
|
26
|
+
# @param character_count_attribute [String] the name of the field as it will appear in the textarea
|
27
|
+
# @param context [ActionView::Base] the view context
|
28
|
+
# @param character_count_options (see CCS::Components::GovUK::Field::Input::CharacterCount.get_character_count_from_group_options)
|
29
|
+
# @param after_input [String] Text or HTML that goes after the input
|
30
|
+
#
|
31
|
+
# @option (see CCS::Components::GovUK::Field::Input::CharacterCount.get_character_count_from_group_options)
|
32
|
+
|
33
|
+
def initialize(character_count_attribute:, context:, character_count_options:, after_input: nil)
|
34
|
+
count_message = character_count_options[:textarea_description] || {}
|
35
|
+
|
36
|
+
count_message_length = character_count_options[:maxwords] || character_count_options[:maxlength]
|
37
|
+
count_message_default = "You can enter up to %<count>s #{character_count_options[:maxwords] ? 'words' : 'characters'}"
|
38
|
+
|
39
|
+
text = count_message_length ? format(count_message[:count_message] || count_message_default, count: count_message_length) : ''
|
40
|
+
classes = "govuk-character-count__message #{count_message[:classes]}".rstrip
|
41
|
+
|
42
|
+
@count_message = Hint.new(text: text, classes: classes, attributes: { id: "#{character_count_attribute}-info" }, context: context)
|
43
|
+
@after_input = after_input
|
44
|
+
end
|
45
|
+
|
46
|
+
# Generates the HTML for the GOV.UK Character count message
|
47
|
+
#
|
48
|
+
# @return [ActiveSupport::SafeBuffer]
|
49
|
+
|
50
|
+
def render
|
51
|
+
capture do
|
52
|
+
concat(count_message.render)
|
53
|
+
concat(after_input) if after_input
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative 'textarea'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'character_count/count_message'
|
3
3
|
|
4
4
|
module CCS
|
5
5
|
module Components
|
@@ -15,18 +15,15 @@ module CCS
|
|
15
15
|
#
|
16
16
|
# @!attribute [r] textarea
|
17
17
|
# @return [Textarea] The initialised textarea
|
18
|
-
# @!attribute [r]
|
19
|
-
# @return [Hint] The initialised character count
|
18
|
+
# @!attribute [r] textarea_description
|
19
|
+
# @return [Hint] The initialised character count textarea description
|
20
20
|
# @!attribute [r] character_count_html_options
|
21
21
|
# @return [Hash] HTML options for the character count
|
22
22
|
|
23
23
|
class CharacterCount
|
24
|
-
include ActionView::Context
|
25
|
-
include ActionView::Helpers
|
26
|
-
|
27
24
|
private
|
28
25
|
|
29
|
-
attr_reader :textarea, :
|
26
|
+
attr_reader :textarea, :textarea_description
|
30
27
|
|
31
28
|
public
|
32
29
|
|
@@ -38,24 +35,13 @@ module CCS
|
|
38
35
|
#
|
39
36
|
# @option (see initialise_character_count_html_options)
|
40
37
|
|
41
|
-
def initialize(attribute:,
|
38
|
+
def initialize(attribute:, context:, character_count_options: {}, **options)
|
42
39
|
character_count_attribute = options[:form] ? "#{options[:form].object_name}_#{attribute}" : attribute
|
43
40
|
|
44
|
-
initialise_textarea(attribute, character_count_attribute, context, options)
|
45
|
-
initialise_character_count_html_options(character_count_options)
|
46
|
-
initialise_fallback_hint(character_count_attribute, context, character_count_options)
|
41
|
+
initialise_textarea(attribute, character_count_attribute, character_count_options, context, options)
|
47
42
|
end
|
48
43
|
|
49
|
-
|
50
|
-
#
|
51
|
-
# @return [ActiveSupport::SafeBuffer]
|
52
|
-
|
53
|
-
def render
|
54
|
-
tag.div(**character_count_html_options) do
|
55
|
-
concat(textarea.render)
|
56
|
-
concat(fallback_hint.render)
|
57
|
-
end
|
58
|
-
end
|
44
|
+
delegate :render, to: :textarea
|
59
45
|
|
60
46
|
private
|
61
47
|
|
@@ -63,19 +49,23 @@ module CCS
|
|
63
49
|
#
|
64
50
|
# @param attribute [Symbol] the attribute of the field
|
65
51
|
# @param character_count_attribute [String] the name of the field as it will appear in the textarea
|
52
|
+
# @param character_count_options [Hash] options for the character count
|
66
53
|
# @param context [ActionView::Base] the view context
|
67
54
|
# @param options [Hash] options that will be used for the textarea
|
68
55
|
#
|
69
56
|
# @option (see CCS::Components::GovUK::Field::Input::Textarea#initialize)
|
70
57
|
|
71
|
-
def initialise_textarea(attribute, character_count_attribute, context, options)
|
58
|
+
def initialise_textarea(attribute, character_count_attribute, character_count_options, context, options)
|
59
|
+
set_character_count_from_group_options(character_count_options, options)
|
60
|
+
|
72
61
|
((options[:attributes] ||= {})[:aria] ||= {})[:describedby] = [options.dig(:attributes, :aria, :describedby), "#{character_count_attribute}-info"].compact.join(' ')
|
73
|
-
options[:classes] = "#{options[:classes]}
|
62
|
+
options[:classes] = "govuk-js-character-count #{options[:classes]}".rstrip
|
74
63
|
|
75
|
-
|
64
|
+
count_message = CountMessage.new(character_count_attribute: character_count_attribute, context: context, character_count_options: character_count_options, after_input: options.delete(:after_input))
|
65
|
+
@textarea = Textarea.new(attribute: attribute, context: context, after_input: count_message.render, **options)
|
76
66
|
end
|
77
67
|
|
78
|
-
#
|
68
|
+
# Sets the charcter count form group options
|
79
69
|
#
|
80
70
|
# @param character_count_options [Hash] options for the charcter count
|
81
71
|
#
|
@@ -87,40 +77,63 @@ module CCS
|
|
87
77
|
# If +maxwords+ is provided, the +maxlength+ option will be ignored.
|
88
78
|
# @option character_count_options [String] :threshold the percentage value of the limit at which point the count message is displayed.
|
89
79
|
# If this attribute is set, the count message will be hidden by default.
|
90
|
-
# @option character_count_options [Hash] :
|
80
|
+
# @option character_count_options [Hash] :textarea_description ({}) additional parameters that will be used to create the hint containing the character count text:
|
91
81
|
# - +:count_message+ replaced the default text for the count message.
|
92
82
|
# If you want the count number to appear, put %<count>s in the string and it will be replaced with the number
|
93
|
-
# - +classes+ additional CSS classes for the
|
94
|
-
|
95
|
-
|
96
|
-
|
83
|
+
# - +classes+ additional CSS classes for the textarea description HTML
|
84
|
+
# @option character_count_options [String] :characters_under_limit Message displayed when the number of characters is under the configured maximum, maxlength
|
85
|
+
# @option character_count_options [String] :characters_at_limit_text Message displayed when the number of characters reaches the configured maximum, maxlength
|
86
|
+
# @option character_count_options [String] :characters_over_limit Message displayed when the number of characters is over the configured maximum, maxlength
|
87
|
+
# @option character_count_options [String] :words_under_limit Message displayed when the number of words is under the configured maximum, maxwords
|
88
|
+
# @option character_count_options [String] :words_at_limit_text Message displayed when the number of words reaches the configured maximum, maxwords
|
89
|
+
# @option character_count_options [String] :words_over_limit Message displayed when the number of words is over the configured maximum, maxwords
|
90
|
+
|
91
|
+
def set_character_count_from_group_options(character_count_options, options)
|
92
|
+
(options[:form_group] ||= {})[:classes] = "govuk-character-count #{options.dig(:form_group, :classes)}".rstrip
|
93
|
+
((options[:form_group][:attributes] ||= {})[:data] ||= {})[:module] = 'govuk-character-count'
|
97
94
|
|
98
95
|
%i[maxlength threshold maxwords].each do |data_attribute|
|
99
|
-
|
96
|
+
options[:form_group][:attributes][:data][data_attribute] = character_count_options[data_attribute].to_s if character_count_options[data_attribute]
|
100
97
|
end
|
101
98
|
|
102
|
-
|
99
|
+
get_chacrter_count_translations(character_count_options) do |data_attribute, value|
|
100
|
+
options[:form_group][:attributes][:data][data_attribute] = value
|
101
|
+
end
|
103
102
|
end
|
104
103
|
|
105
|
-
#
|
104
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
105
|
+
|
106
|
+
# Generator for the translation options for character count
|
106
107
|
#
|
107
|
-
# @param character_count_attribute [String] the name of the field as it will appear in the textarea
|
108
|
-
# @param context [ActionView::Base] the view context
|
109
108
|
# @param (see initialise_character_count_html_options)
|
110
109
|
#
|
111
110
|
# @option (see initialise_character_count_html_options)
|
111
|
+
#
|
112
|
+
# @return [Hash]
|
112
113
|
|
113
|
-
def
|
114
|
-
|
114
|
+
def get_chacrter_count_translations(character_count_options)
|
115
|
+
%i[characters_at_limit words_at_limit].each do |data_attribute|
|
116
|
+
data_attribute_name = :"#{data_attribute}_text"
|
115
117
|
|
116
|
-
|
117
|
-
|
118
|
+
next unless character_count_options[data_attribute_name]
|
119
|
+
|
120
|
+
yield :"i18n.#{data_attribute.to_s.gsub('_', '-')}", character_count_options[data_attribute_name]
|
121
|
+
end
|
118
122
|
|
119
|
-
|
120
|
-
|
123
|
+
%i[characters_under_limit characters_over_limit words_under_limit words_over_limit].each do |data_attribute|
|
124
|
+
next unless character_count_options[data_attribute]
|
121
125
|
|
122
|
-
|
126
|
+
%i[other one].each do |plural_rule|
|
127
|
+
next unless character_count_options[data_attribute][plural_rule]
|
128
|
+
|
129
|
+
yield :"i18n.#{data_attribute.to_s.gsub('_', '-')}.#{plural_rule}", character_count_options[data_attribute][plural_rule]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
yield :'i18n.textarea-description.other', character_count_options[:textarea_description][:count_message] if character_count_options.dig(:textarea_description, :count_message) && !(character_count_options[:maxwords] || character_count_options[:maxlength])
|
123
134
|
end
|
135
|
+
|
136
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
124
137
|
end
|
125
138
|
end
|
126
139
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require_relative '../../../button'
|
2
|
+
|
3
|
+
module CCS
|
4
|
+
module Components
|
5
|
+
module GovUK
|
6
|
+
class Field < Base
|
7
|
+
class Input < Field
|
8
|
+
class PasswordInput
|
9
|
+
# = GOV.UK Password input show/hide button
|
10
|
+
#
|
11
|
+
# This is used to generate the password input show/hide button
|
12
|
+
#
|
13
|
+
# @!attribute [r] show_hide_button
|
14
|
+
# @return [Button] Show/Hide button
|
15
|
+
# @!attribute [r] after_input
|
16
|
+
# @return [String] Text or HTML for after the textarea input
|
17
|
+
|
18
|
+
class ShowHideButton
|
19
|
+
include ActionView::Context
|
20
|
+
include ActionView::Helpers
|
21
|
+
include ActionView::Helpers::FormTagHelper
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :show_hide_button, :after_input
|
26
|
+
|
27
|
+
public
|
28
|
+
|
29
|
+
# @param attribute [String] the name of the field as it will appear in the input
|
30
|
+
# @param context [ActionView::Base] the view context
|
31
|
+
# @param button [Hash] options for the button
|
32
|
+
# @param after_input [String] Text or HTML that goes after the input
|
33
|
+
#
|
34
|
+
# @option button [String] :classes classes to add to the button
|
35
|
+
#
|
36
|
+
# @option (see CCS::Components::GovUK::Field::Input::PasswordInput.set_password_input_from_group_options)
|
37
|
+
|
38
|
+
def initialize(attribute:, context:, button: {}, after_input: nil, **options)
|
39
|
+
button[:classes] = "govuk-button--secondary govuk-password-input__toggle govuk-js-password-input-toggle #{button[:classes]}".rstrip
|
40
|
+
button[:attributes] = {
|
41
|
+
type: :button,
|
42
|
+
aria: {
|
43
|
+
controls: options.dig(:attributes, :id) || field_id(options[:form]&.object_name, attribute),
|
44
|
+
label: options[:show_password_aria_label_text] || 'Show password'
|
45
|
+
},
|
46
|
+
hidden: {
|
47
|
+
value: true,
|
48
|
+
optional: true
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
@show_hide_button = Button.new(text: options[:show_password_text] || 'Show', context: context, classes: button[:classes], attributes: button[:attributes])
|
53
|
+
@after_input = after_input
|
54
|
+
end
|
55
|
+
|
56
|
+
# Generates the HTML for the GOV.UK Password input show/hide button
|
57
|
+
#
|
58
|
+
# @return [ActiveSupport::SafeBuffer]
|
59
|
+
|
60
|
+
def render
|
61
|
+
capture do
|
62
|
+
concat(show_hide_button.render)
|
63
|
+
concat(after_input) if after_input
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative 'text_input'
|
2
|
+
require_relative 'password_input/show_hide_button'
|
3
|
+
|
4
|
+
module CCS
|
5
|
+
module Components
|
6
|
+
module GovUK
|
7
|
+
class Field < Base
|
8
|
+
class Input < Field
|
9
|
+
# = GOV.UK Password input
|
10
|
+
#
|
11
|
+
# This is used for generating the password input component from the
|
12
|
+
# {https://design-system.service.gov.uk/components/password-input GDS - Components - Password Input}
|
13
|
+
#
|
14
|
+
# @!attribute [r] text_input
|
15
|
+
# @return [CCS::Components::GovUK::Field::Input::TextInput] Initialised text input component
|
16
|
+
|
17
|
+
class PasswordInput
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :text_input
|
21
|
+
|
22
|
+
public
|
23
|
+
|
24
|
+
# @param (see CCS::Components::GovUK::Field::Input::TextInput#initialize)
|
25
|
+
#
|
26
|
+
# @option (see CCS::Components::GovUK::Field::Input::TextInput#initialize)
|
27
|
+
|
28
|
+
def initialize(attribute:, context:, **options)
|
29
|
+
set_password_input_from_group_options(options)
|
30
|
+
|
31
|
+
show_hide_button = ShowHideButton.new(attribute: attribute, context: context, after_input: options.delete(:after_input), **options)
|
32
|
+
|
33
|
+
options[:attributes] ||= {}
|
34
|
+
options[:attributes][:spellcheck] = false
|
35
|
+
options[:attributes][:autocapitalize] = 'none'
|
36
|
+
options[:attributes][:autocomplete] ||= 'current-password'
|
37
|
+
|
38
|
+
@text_input = TextInput.new(
|
39
|
+
context: context,
|
40
|
+
attribute: attribute,
|
41
|
+
after_input: show_hide_button.render,
|
42
|
+
input_wrapper: {
|
43
|
+
classes: 'govuk-password-input__wrapper'
|
44
|
+
},
|
45
|
+
classes: "govuk-password-input__input govuk-js-password-input-input #{options.delete(:classes)}".rstrip,
|
46
|
+
field_type: :password,
|
47
|
+
**options
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
delegate :render, to: :text_input
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# rubocop:disable Naming/AccessorMethodName
|
56
|
+
|
57
|
+
# Sets the password input form group options
|
58
|
+
#
|
59
|
+
# @param options [Hash] options for the password input
|
60
|
+
#
|
61
|
+
# @option options [String] :show_password_text button text when the password is hidden
|
62
|
+
# @option options [String] :hide_password_text button text when the password is visible
|
63
|
+
# @option options [String] :show_password_aria_label_text button text exposed to assistive technologies, like screen readers, when the password is hidden
|
64
|
+
# @option options [String] :hide_password_aria_label_text button text exposed to assistive technologies, like screen readers, when the password is visible
|
65
|
+
# @option options [String] :password_shown_announcement_text announcement made to screen reader users when their password has become visible in plain text
|
66
|
+
# @option options [String] :password_hidden_announcement_text announcement made to screen reader users when their password has been obscured and is not visible
|
67
|
+
|
68
|
+
def set_password_input_from_group_options(options)
|
69
|
+
(options[:form_group] ||= {})[:classes] = "govuk-password-input #{options.dig(:form_group, :classes)}".rstrip
|
70
|
+
((options[:form_group][:attributes] ||= {})[:data] ||= {})[:module] = 'govuk-password-input'
|
71
|
+
|
72
|
+
get_password_input_translations(options) do |data_attribute, value|
|
73
|
+
options[:form_group][:attributes][:data][data_attribute] = value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# rubocop:enable Naming/AccessorMethodName
|
78
|
+
|
79
|
+
# Generator for the translation options for password input
|
80
|
+
#
|
81
|
+
# @param (see initialise_password_input_html_options)
|
82
|
+
#
|
83
|
+
# @option (see initialise_password_input_html_options)
|
84
|
+
#
|
85
|
+
# @yield Data attribute key and the value
|
86
|
+
|
87
|
+
def get_password_input_translations(password_input_options)
|
88
|
+
%i[show_password hide_password show_password_aria_label hide_password_aria_label password_shown_announcement password_hidden_announcement].each do |data_attribute|
|
89
|
+
data_attribute_name = :"#{data_attribute}_text"
|
90
|
+
|
91
|
+
next unless password_input_options[data_attribute_name]
|
92
|
+
|
93
|
+
yield :"i18n.#{data_attribute.to_s.gsub('_', '-')}", password_input_options[data_attribute_name]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -38,8 +38,8 @@ module CCS
|
|
38
38
|
@items = items.map do |item|
|
39
39
|
[
|
40
40
|
item[:text] || item[:value],
|
41
|
-
item[:value],
|
42
|
-
|
41
|
+
item[:value].nil? ? item[:text] : item[:value],
|
42
|
+
item[:attributes] || {}
|
43
43
|
]
|
44
44
|
end
|
45
45
|
@selected = @options[:model] ? @options[:model].send(attribute) : selected
|
@@ -19,11 +19,13 @@ module CCS
|
|
19
19
|
# @return [Fix] The initialised prefix
|
20
20
|
# @!attribute [r] suffix
|
21
21
|
# @return [Fix] The initialised suffix
|
22
|
+
# @!attribute [r] input_wrapper_html_options
|
23
|
+
# @return [Fix] HTML options for the input wrapper
|
22
24
|
|
23
25
|
class TextInput < Input
|
24
26
|
private
|
25
27
|
|
26
|
-
attr_reader :field_type, :value, :prefix, :suffix
|
28
|
+
attr_reader :field_type, :value, :prefix, :suffix, :input_wrapper_html_options
|
27
29
|
|
28
30
|
public
|
29
31
|
|
@@ -36,33 +38,41 @@ module CCS
|
|
36
38
|
# see {CCS::Components::GovUK::Field::Input::TextInput::Fix#initialize Fix#initialize} for more details.
|
37
39
|
# @param suffix [Hash] optional suffix for the input field,
|
38
40
|
# see {CCS::Components::GovUK::Field::Input::TextInput::Fix#initialize Fix#initialize} for more details.
|
41
|
+
# @param input_wrapper [Hash] HTML options for the input wrapper
|
39
42
|
#
|
40
43
|
# @option (see CCS::Components::GovUK::Field::Input#initialize)
|
41
44
|
|
42
|
-
def initialize(attribute:, field_type: :text, value: nil, prefix: nil, suffix: nil, **options)
|
45
|
+
def initialize(attribute:, field_type: :text, value: nil, prefix: nil, suffix: nil, input_wrapper: {}, **options)
|
43
46
|
super(attribute: attribute, **options)
|
44
47
|
|
45
48
|
@field_type = :"#{field_type}_field"
|
46
49
|
@value = @options[:model] ? @options[:model].send(attribute) : value
|
47
50
|
@prefix = Fix.new(fix: 'pre', context: @context, **prefix) if prefix
|
48
51
|
@suffix = Fix.new(fix: 'suf', context: @context, **suffix) if suffix
|
52
|
+
@input_wrapper_html_options = {
|
53
|
+
class: "govuk-input__wrapper #{input_wrapper[:classes]}".rstrip
|
54
|
+
}.merge(input_wrapper[:attributes] || {})
|
49
55
|
end
|
50
56
|
|
51
57
|
# rubocop:enable Metrics/ParameterLists
|
58
|
+
# rubocop:disable Metrics/AbcSize
|
52
59
|
|
53
60
|
# Generates the HTML for the GOV.UK Text Input component
|
54
61
|
#
|
55
62
|
# @return [ActiveSupport::SafeBuffer]
|
56
63
|
|
57
64
|
def render
|
58
|
-
|
59
|
-
|
65
|
+
form_group.render do |display_error_message|
|
66
|
+
concat(label.render)
|
67
|
+
concat(hint.render) if hint
|
68
|
+
concat(display_error_message)
|
69
|
+
concat(text_input_wrapper do
|
60
70
|
if options[:form]
|
61
71
|
options[:form].send(field_type, attribute, **options[:attributes])
|
62
72
|
else
|
63
73
|
context.send("#{field_type}_tag", attribute, value, **options[:attributes])
|
64
74
|
end
|
65
|
-
end
|
75
|
+
end)
|
66
76
|
end
|
67
77
|
end
|
68
78
|
|
@@ -72,6 +82,8 @@ module CCS
|
|
72
82
|
|
73
83
|
private
|
74
84
|
|
85
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
86
|
+
|
75
87
|
# Wrapper method used by {render} to wrap the text input with a prefix or suffix if they exist
|
76
88
|
#
|
77
89
|
# @yield the text input HTML
|
@@ -79,16 +91,20 @@ module CCS
|
|
79
91
|
# @return [ActiveSupport::SafeBuffer]
|
80
92
|
|
81
93
|
def text_input_wrapper
|
82
|
-
if prefix || suffix
|
83
|
-
tag.div(
|
94
|
+
if prefix || suffix || before_input || after_input
|
95
|
+
tag.div(**input_wrapper_html_options) do
|
96
|
+
concat(before_input) if before_input
|
84
97
|
concat(prefix.render) if prefix
|
85
98
|
concat(yield)
|
86
99
|
concat(suffix.render) if suffix
|
100
|
+
concat(after_input) if after_input
|
87
101
|
end
|
88
102
|
else
|
89
103
|
yield
|
90
104
|
end
|
91
105
|
end
|
106
|
+
|
107
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
92
108
|
end
|
93
109
|
end
|
94
110
|
end
|
@@ -25,6 +25,8 @@ module CCS
|
|
25
25
|
|
26
26
|
# @param (see CCS::Components::GovUK::Field#initialize)
|
27
27
|
# @param label [Hash] attributes for the label, see {CCS::Components::GovUK::Label#initialize Label#initialize} for more details.
|
28
|
+
# @param before_input [String] text or HTML to go before the input
|
29
|
+
# @param after_input [String] text or HTML to go after the input
|
28
30
|
#
|
29
31
|
# @option (see CCS::Components::GovUK::Field#initialize)
|
30
32
|
|
@@ -52,7 +54,9 @@ module CCS
|
|
52
54
|
concat(label.render)
|
53
55
|
concat(hint.render) if hint
|
54
56
|
concat(display_error_message)
|
57
|
+
concat(before_input) if before_input
|
55
58
|
concat(yield)
|
59
|
+
concat(after_input) if after_input
|
56
60
|
end
|
57
61
|
end
|
58
62
|
end
|
@@ -12,18 +12,9 @@ module CCS
|
|
12
12
|
#
|
13
13
|
# This is used for generating the checkboxes component from the
|
14
14
|
# {https://design-system.service.gov.uk/components/checkboxes GDS - Components - Checkboxes}
|
15
|
-
#
|
16
|
-
# @!attribute [r] checkbox_items
|
17
|
-
# @return [Array<Item::Divider|Item::Checkbox|Item::Checkbox>] An array of the initialised checkbox items
|
18
15
|
|
19
16
|
class Checkboxes < Inputs
|
20
|
-
|
21
|
-
|
22
|
-
attr_reader :checkbox_items
|
23
|
-
|
24
|
-
public
|
25
|
-
|
26
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
17
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
|
27
18
|
|
28
19
|
# @param (see CCS::Components::GovUK::Field::Inputs#initialize)
|
29
20
|
# @param checkbox_items [Array<Hash>] an array of options for the checkboxes.
|
@@ -34,29 +25,18 @@ module CCS
|
|
34
25
|
def initialize(attribute:, checkbox_items:, **options)
|
35
26
|
super(attribute: attribute, **options)
|
36
27
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
28
|
+
@options[:values] ||= []
|
29
|
+
@options[:values] = (@options[:model] || @options[:form].object).send(attribute) || [] if @options[:model] || @options[:form]
|
30
|
+
|
31
|
+
checkbox_items.each { |checkbox_item| checkbox_item[:checked] = @options[:values].include?(checkbox_item[:value]) } if @options[:values].any?
|
32
|
+
checkbox_items.each { |checkbox_item| set_described_by(checkbox_item, @attribute, @error_message, @hint&.send(:options)) } unless @fieldset
|
41
33
|
|
42
34
|
checkbox_item_class = @options[:form] ? Item::Checkbox::Form : Inputs::Item::Checkbox::Tag
|
43
35
|
|
44
|
-
@
|
36
|
+
@input_items = checkbox_items.map { |checkbox_item| checkbox_item[:divider] ? Item::Divider.new(divider: checkbox_item[:divider], type: 'checkboxes') : checkbox_item_class.new(attribute: attribute, form: @options[:form], context: @context, **checkbox_item) }
|
45
37
|
end
|
46
38
|
|
47
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
48
|
-
|
49
|
-
# Generates the HTML for the GOV.UK Checkboxes component
|
50
|
-
#
|
51
|
-
# @return [ActiveSupport::SafeBuffer]
|
52
|
-
|
53
|
-
def render
|
54
|
-
super() do
|
55
|
-
tag.div(**options[:attributes]) do
|
56
|
-
checkbox_items.each { |checkbox_item| concat(checkbox_item.render) }
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
39
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
|
60
40
|
|
61
41
|
# The default attributes for the checkboxes
|
62
42
|
|