ccs-frontend_helpers 0.1.2 → 0.3.0
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.
- 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
|
|