govuk_design_system_formbuilder 1.2.0 → 1.2.5
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/lib/govuk_design_system_formbuilder.rb +4 -0
- data/lib/govuk_design_system_formbuilder/base.rb +5 -0
- data/lib/govuk_design_system_formbuilder/builder.rb +52 -33
- data/lib/govuk_design_system_formbuilder/containers/character_count.rb +8 -7
- data/lib/govuk_design_system_formbuilder/containers/check_boxes.rb +18 -10
- data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +27 -18
- data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +15 -55
- data/lib/govuk_design_system_formbuilder/containers/form_group.rb +18 -10
- data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +28 -19
- data/lib/govuk_design_system_formbuilder/containers/radios.rb +22 -11
- data/lib/govuk_design_system_formbuilder/containers/supplemental.rb +3 -3
- data/lib/govuk_design_system_formbuilder/elements/caption.rb +8 -6
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +29 -23
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +17 -15
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +28 -32
- data/lib/govuk_design_system_formbuilder/elements/date.rb +55 -51
- data/lib/govuk_design_system_formbuilder/elements/error_message.rb +7 -6
- data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +24 -27
- data/lib/govuk_design_system_formbuilder/elements/file.rb +21 -22
- data/lib/govuk_design_system_formbuilder/elements/hint.rb +13 -16
- data/lib/govuk_design_system_formbuilder/elements/inputs/email.rb +2 -0
- data/lib/govuk_design_system_formbuilder/elements/label.rb +40 -29
- data/lib/govuk_design_system_formbuilder/elements/legend.rb +79 -0
- data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +46 -36
- data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +24 -14
- data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +18 -19
- data/lib/govuk_design_system_formbuilder/elements/select.rb +28 -34
- data/lib/govuk_design_system_formbuilder/elements/submit.rb +34 -25
- data/lib/govuk_design_system_formbuilder/elements/text_area.rb +39 -40
- data/lib/govuk_design_system_formbuilder/traits/caption.rb +5 -6
- data/lib/govuk_design_system_formbuilder/traits/input.rb +21 -29
- data/lib/govuk_design_system_formbuilder/traits/label.rb +2 -2
- data/lib/govuk_design_system_formbuilder/version.rb +1 -1
- metadata +16 -15
@@ -9,35 +9,37 @@ module GOVUKDesignSystemFormBuilder
|
|
9
9
|
|
10
10
|
SEGMENTS = { day: '3i', month: '2i', year: '1i' }.freeze
|
11
11
|
|
12
|
-
def initialize(builder, object_name, attribute_name, legend:, caption:, hint_text:, date_of_birth: false, omit_day:, &block)
|
12
|
+
def initialize(builder, object_name, attribute_name, legend:, caption:, hint_text:, date_of_birth: false, omit_day:, form_group_classes:, &block)
|
13
13
|
super(builder, object_name, attribute_name, &block)
|
14
14
|
|
15
|
-
@legend
|
16
|
-
@caption
|
17
|
-
@hint_text
|
18
|
-
@date_of_birth
|
19
|
-
@omit_day
|
15
|
+
@legend = legend
|
16
|
+
@caption = caption
|
17
|
+
@hint_text = hint_text
|
18
|
+
@date_of_birth = date_of_birth
|
19
|
+
@omit_day = omit_day
|
20
|
+
@form_group_classes = form_group_classes
|
20
21
|
end
|
21
22
|
|
22
23
|
def html
|
23
|
-
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
24
|
-
Containers::Fieldset.new(@builder, @object_name, @attribute_name,
|
25
|
-
safe_join(
|
26
|
-
[
|
27
|
-
supplemental_content.html,
|
28
|
-
hint_element.html,
|
29
|
-
error_element.html,
|
30
|
-
content_tag('div', class: %(#{brand}-date-input)) do
|
31
|
-
safe_join([day, month, year])
|
32
|
-
end
|
33
|
-
]
|
34
|
-
)
|
24
|
+
Containers::FormGroup.new(@builder, @object_name, @attribute_name, classes: @form_group_classes).html do
|
25
|
+
Containers::Fieldset.new(@builder, @object_name, @attribute_name, **fieldset_options).html do
|
26
|
+
safe_join([supplemental_content, hint_element, error_element, date])
|
35
27
|
end
|
36
28
|
end
|
37
29
|
end
|
38
30
|
|
39
31
|
private
|
40
32
|
|
33
|
+
def fieldset_options
|
34
|
+
{ legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id] }
|
35
|
+
end
|
36
|
+
|
37
|
+
def date
|
38
|
+
content_tag('div', class: %(#{brand}-date-input)) do
|
39
|
+
safe_join([day, month, year])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
41
43
|
def omit_day?
|
42
44
|
@omit_day
|
43
45
|
end
|
@@ -45,61 +47,59 @@ module GOVUKDesignSystemFormBuilder
|
|
45
47
|
def day
|
46
48
|
return nil if omit_day?
|
47
49
|
|
48
|
-
|
50
|
+
date_part(:day, width: 2, link_errors: true)
|
49
51
|
end
|
50
52
|
|
51
53
|
def month
|
52
|
-
|
54
|
+
date_part(:month, width: 2, link_errors: omit_day?)
|
53
55
|
end
|
54
56
|
|
55
57
|
def year
|
56
|
-
|
58
|
+
date_part(:year, width: 4)
|
57
59
|
end
|
58
60
|
|
59
|
-
def
|
61
|
+
def date_part(segment, width:, link_errors: false)
|
60
62
|
value = @builder.object.try(@attribute_name).try(segment)
|
61
63
|
|
62
64
|
content_tag('div', class: %w(date-input__item).prefix(brand)) do
|
63
65
|
content_tag('div', class: %w(form-group).prefix(brand)) do
|
64
|
-
safe_join(
|
65
|
-
[
|
66
|
-
tag.label(
|
67
|
-
segment.capitalize,
|
68
|
-
class: date_input_label_classes,
|
69
|
-
for: date_attribute_id(segment, link_errors)
|
70
|
-
),
|
71
|
-
|
72
|
-
tag.input(
|
73
|
-
id: date_attribute_id(segment, link_errors),
|
74
|
-
class: date_input_classes(width),
|
75
|
-
name: date_attribute_name(segment),
|
76
|
-
type: 'text',
|
77
|
-
pattern: '[0-9]*',
|
78
|
-
inputmode: 'numeric',
|
79
|
-
value: value,
|
80
|
-
autocomplete: date_of_birth_autocomplete_value(segment)
|
81
|
-
)
|
82
|
-
]
|
83
|
-
)
|
66
|
+
safe_join([label(segment, link_errors), input(segment, link_errors, width, value)])
|
84
67
|
end
|
85
68
|
end
|
86
69
|
end
|
87
70
|
|
88
|
-
def
|
71
|
+
def label(segment, link_errors)
|
72
|
+
tag.label(
|
73
|
+
segment.capitalize,
|
74
|
+
class: label_classes,
|
75
|
+
for: id(segment, link_errors)
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def input(segment, link_errors, width, value)
|
80
|
+
tag.input(
|
81
|
+
id: id(segment, link_errors),
|
82
|
+
class: classes(width),
|
83
|
+
name: name(segment),
|
84
|
+
type: 'text',
|
85
|
+
pattern: '[0-9]*',
|
86
|
+
inputmode: 'numeric',
|
87
|
+
value: value,
|
88
|
+
autocomplete: date_of_birth_autocomplete_value(segment)
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
def classes(width)
|
89
93
|
%w(input date-input__input).prefix(brand).tap do |classes|
|
90
94
|
classes.push(%(#{brand}-input--width-#{width}))
|
91
95
|
classes.push(%(#{brand}-input--error)) if has_errors?
|
92
96
|
end
|
93
97
|
end
|
94
98
|
|
95
|
-
def date_input_label_classes
|
96
|
-
%w(label date-input__label).prefix(brand)
|
97
|
-
end
|
98
|
-
|
99
99
|
# if the field has errors we want the govuk_error_summary to
|
100
100
|
# be able to link to the day field. Otherwise, generate IDs
|
101
101
|
# in the normal fashion
|
102
|
-
def
|
102
|
+
def id(segment, link_errors)
|
103
103
|
if has_errors? && link_errors
|
104
104
|
field_id(link_errors: link_errors)
|
105
105
|
else
|
@@ -107,11 +107,11 @@ module GOVUKDesignSystemFormBuilder
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
def
|
110
|
+
def name(segment)
|
111
111
|
format(
|
112
|
-
"%<object_name>s[%<
|
112
|
+
"%<object_name>s[%<input_name>s(%<segment>s)]",
|
113
113
|
object_name: @object_name,
|
114
|
-
|
114
|
+
input_name: @attribute_name,
|
115
115
|
segment: SEGMENTS.fetch(segment)
|
116
116
|
)
|
117
117
|
end
|
@@ -121,6 +121,10 @@ module GOVUKDesignSystemFormBuilder
|
|
121
121
|
|
122
122
|
{ day: 'bday-day', month: 'bday-month', year: 'bday-year' }.fetch(segment)
|
123
123
|
end
|
124
|
+
|
125
|
+
def label_classes
|
126
|
+
%w(label date-input__label).prefix(brand)
|
127
|
+
end
|
124
128
|
end
|
125
129
|
end
|
126
130
|
end
|
@@ -13,15 +13,16 @@ module GOVUKDesignSystemFormBuilder
|
|
13
13
|
return nil unless has_errors?
|
14
14
|
|
15
15
|
content_tag('span', class: %(#{brand}-error-message), id: error_id) do
|
16
|
-
safe_join(
|
17
|
-
[
|
18
|
-
tag.span('Error: ', class: %(#{brand}-visually-hidden)),
|
19
|
-
message
|
20
|
-
]
|
21
|
-
)
|
16
|
+
safe_join([prefix, message])
|
22
17
|
end
|
23
18
|
end
|
24
19
|
|
20
|
+
private
|
21
|
+
|
22
|
+
def prefix
|
23
|
+
tag.span('Error: ', class: %(#{brand}-visually-hidden))
|
24
|
+
end
|
25
|
+
|
25
26
|
def message
|
26
27
|
@builder.object.errors.messages[@attribute_name]&.first
|
27
28
|
end
|
@@ -12,38 +12,35 @@ module GOVUKDesignSystemFormBuilder
|
|
12
12
|
def html
|
13
13
|
return nil unless object_has_errors?
|
14
14
|
|
15
|
-
content_tag('div', class: summary_class, **
|
16
|
-
safe_join(
|
17
|
-
[
|
18
|
-
tag.h2(@title, id: error_summary_title_id, class: summary_class('title')),
|
19
|
-
content_tag('div', class: summary_class('body')) do
|
20
|
-
content_tag('ul', class: [%(#{brand}-list), summary_class('list')]) do
|
21
|
-
safe_join(
|
22
|
-
@builder.object.errors.messages.map do |attribute, messages|
|
23
|
-
error_list_item(attribute, messages.first)
|
24
|
-
end
|
25
|
-
)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
]
|
29
|
-
)
|
15
|
+
content_tag('div', class: summary_class, **summary_options) do
|
16
|
+
safe_join([title, summary])
|
30
17
|
end
|
31
18
|
end
|
32
19
|
|
33
20
|
private
|
34
21
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
22
|
+
def title
|
23
|
+
tag.h2(@title, id: summary_title_id, class: summary_class('title'))
|
24
|
+
end
|
25
|
+
|
26
|
+
def summary
|
27
|
+
content_tag('div', class: summary_class('body')) do
|
28
|
+
content_tag('ul', class: [%(#{brand}-list), summary_class('list')]) do
|
29
|
+
safe_join(list)
|
30
|
+
end
|
44
31
|
end
|
45
32
|
end
|
46
33
|
|
34
|
+
def list
|
35
|
+
@builder.object.errors.messages.map do |attribute, messages|
|
36
|
+
list_item(attribute, messages.first)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def list_item(attribute, message)
|
41
|
+
tag.li(link_to(message, same_page_link(field_id(attribute)), data: { turbolinks: false }))
|
42
|
+
end
|
43
|
+
|
47
44
|
def same_page_link(target)
|
48
45
|
'#'.concat(target)
|
49
46
|
end
|
@@ -60,7 +57,7 @@ module GOVUKDesignSystemFormBuilder
|
|
60
57
|
build_id('field-error', attribute_name: attribute)
|
61
58
|
end
|
62
59
|
|
63
|
-
def
|
60
|
+
def summary_title_id
|
64
61
|
'error-summary-title'
|
65
62
|
end
|
66
63
|
|
@@ -68,7 +65,7 @@ module GOVUKDesignSystemFormBuilder
|
|
68
65
|
@builder.object.errors.any?
|
69
66
|
end
|
70
67
|
|
71
|
-
def
|
68
|
+
def summary_options
|
72
69
|
{
|
73
70
|
tabindex: -1,
|
74
71
|
role: 'alert',
|
@@ -76,7 +73,7 @@ module GOVUKDesignSystemFormBuilder
|
|
76
73
|
module: %(#{brand}-error-summary)
|
77
74
|
},
|
78
75
|
aria: {
|
79
|
-
labelledby:
|
76
|
+
labelledby: summary_title_id
|
80
77
|
}
|
81
78
|
}
|
82
79
|
end
|
@@ -8,38 +8,37 @@ module GOVUKDesignSystemFormBuilder
|
|
8
8
|
include Traits::Label
|
9
9
|
include Traits::Supplemental
|
10
10
|
|
11
|
-
def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, **
|
11
|
+
def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, form_group_classes:, **kwargs, &block)
|
12
12
|
super(builder, object_name, attribute_name, &block)
|
13
13
|
|
14
|
-
@label
|
15
|
-
@caption
|
16
|
-
@hint_text
|
17
|
-
@
|
14
|
+
@label = label
|
15
|
+
@caption = caption
|
16
|
+
@hint_text = hint_text
|
17
|
+
@extra_options = kwargs
|
18
|
+
@form_group_classes = form_group_classes
|
18
19
|
end
|
19
20
|
|
20
21
|
def html
|
21
|
-
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
22
|
-
safe_join(
|
23
|
-
[
|
24
|
-
label_element.html,
|
25
|
-
supplemental_content.html,
|
26
|
-
hint_element.html,
|
27
|
-
error_element.html,
|
28
|
-
@builder.file_field(
|
29
|
-
@attribute_name,
|
30
|
-
id: field_id(link_errors: true),
|
31
|
-
class: file_classes,
|
32
|
-
aria: { describedby: described_by(hint_id, error_id, supplemental_id) },
|
33
|
-
**@extra_args
|
34
|
-
)
|
35
|
-
]
|
36
|
-
)
|
22
|
+
Containers::FormGroup.new(@builder, @object_name, @attribute_name, classes: @form_group_classes).html do
|
23
|
+
safe_join([label_element, supplemental_content, hint_element, error_element, file])
|
37
24
|
end
|
38
25
|
end
|
39
26
|
|
40
27
|
private
|
41
28
|
|
42
|
-
def
|
29
|
+
def file
|
30
|
+
@builder.file_field(@attribute_name, **options, **@extra_options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def options
|
34
|
+
{
|
35
|
+
id: field_id(link_errors: true),
|
36
|
+
class: classes,
|
37
|
+
aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def classes
|
43
42
|
%w(file-upload).prefix(brand).tap do |c|
|
44
43
|
c.push(%(#{brand}-file-upload--error)) if has_errors?
|
45
44
|
end
|
@@ -9,37 +9,34 @@ module GOVUKDesignSystemFormBuilder
|
|
9
9
|
def initialize(builder, object_name, attribute_name, text, value = nil, radio: false, checkbox: false)
|
10
10
|
super(builder, object_name, attribute_name)
|
11
11
|
|
12
|
-
@value
|
13
|
-
@hint_text
|
14
|
-
@
|
15
|
-
@
|
12
|
+
@value = value
|
13
|
+
@hint_text = retrieve_text(text)
|
14
|
+
@radio = radio
|
15
|
+
@checkbox = checkbox
|
16
16
|
end
|
17
17
|
|
18
18
|
def html
|
19
19
|
return nil if @hint_text.blank?
|
20
20
|
|
21
|
-
tag.span(@hint_text, class:
|
21
|
+
tag.span(@hint_text, class: classes, id: hint_id)
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
|
-
def
|
27
|
-
|
28
|
-
supplied.presence,
|
29
|
-
localised_text(:hint)
|
30
|
-
].compact.first
|
26
|
+
def retrieve_text(supplied)
|
27
|
+
supplied.presence || localised_text(:hint)
|
31
28
|
end
|
32
29
|
|
33
|
-
def
|
34
|
-
%w(hint).prefix(brand).push(
|
30
|
+
def classes
|
31
|
+
%w(hint).prefix(brand).push(radio_class, checkbox_class).compact
|
35
32
|
end
|
36
33
|
|
37
|
-
def radio_class
|
38
|
-
radio ? %(#{brand}-radios__hint) : nil
|
34
|
+
def radio_class
|
35
|
+
@radio ? %(#{brand}-radios__hint) : nil
|
39
36
|
end
|
40
37
|
|
41
|
-
def checkbox_class
|
42
|
-
checkbox ? %(#{brand}-checkboxes__hint) : nil
|
38
|
+
def checkbox_class
|
39
|
+
@checkbox ? %(#{brand}-checkboxes__hint) : nil
|
43
40
|
end
|
44
41
|
end
|
45
42
|
end
|
@@ -14,14 +14,14 @@ module GOVUKDesignSystemFormBuilder
|
|
14
14
|
if content
|
15
15
|
@content = content.call
|
16
16
|
else
|
17
|
-
@value
|
18
|
-
@text
|
19
|
-
@size_class
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@tag
|
23
|
-
@link_errors
|
24
|
-
@caption
|
17
|
+
@value = value # used by field_id
|
18
|
+
@text = retrieve_text(text, hidden)
|
19
|
+
@size_class = size_class(size)
|
20
|
+
@radio = radio
|
21
|
+
@checkbox = checkbox
|
22
|
+
@tag = tag
|
23
|
+
@link_errors = link_errors
|
24
|
+
@caption = caption
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -29,26 +29,21 @@ module GOVUKDesignSystemFormBuilder
|
|
29
29
|
return nil if [@content, @text].all?(&:blank?)
|
30
30
|
|
31
31
|
if @tag.present?
|
32
|
-
content_tag(@tag, class: %(#{brand}-label-wrapper)) {
|
32
|
+
content_tag(@tag, class: %(#{brand}-label-wrapper)) { label }
|
33
33
|
else
|
34
|
-
|
34
|
+
label
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
-
def
|
41
|
-
@builder.label(
|
42
|
-
@
|
43
|
-
value: @value,
|
44
|
-
for: field_id(link_errors: @link_errors),
|
45
|
-
class: %w(label).prefix(brand).push(@size_class, @weight_class, @radio_class, @checkbox_class).compact
|
46
|
-
) do
|
47
|
-
@content || safe_join([caption_element.html, @text])
|
40
|
+
def label
|
41
|
+
@builder.label(@attribute_name, **options) do
|
42
|
+
@content || safe_join([caption, @text])
|
48
43
|
end
|
49
44
|
end
|
50
45
|
|
51
|
-
def
|
46
|
+
def retrieve_text(option_text, hidden)
|
52
47
|
text = [option_text, localised_text(:label), @attribute_name.capitalize].compact.first.to_s
|
53
48
|
|
54
49
|
if hidden
|
@@ -58,21 +53,37 @@ module GOVUKDesignSystemFormBuilder
|
|
58
53
|
end
|
59
54
|
end
|
60
55
|
|
61
|
-
def
|
62
|
-
|
56
|
+
def options
|
57
|
+
{
|
58
|
+
value: @value,
|
59
|
+
for: field_id(link_errors: @link_errors),
|
60
|
+
class: %w(label).prefix(brand).push(@size_class, @weight_class, radio_class, checkbox_class).compact
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def caption
|
65
|
+
caption_element.html unless [@radio, @checkbox].any?
|
63
66
|
end
|
64
67
|
|
65
|
-
def
|
66
|
-
|
68
|
+
def radio_class
|
69
|
+
return nil unless @radio
|
70
|
+
|
71
|
+
%(#{brand}-radios__label)
|
72
|
+
end
|
73
|
+
|
74
|
+
def checkbox_class
|
75
|
+
return nil unless @checkbox
|
76
|
+
|
77
|
+
%(#{brand}-checkboxes__label)
|
67
78
|
end
|
68
79
|
|
69
|
-
def
|
80
|
+
def size_class(size)
|
70
81
|
case size
|
71
|
-
when 'xl'
|
72
|
-
when 'l'
|
73
|
-
when 'm'
|
74
|
-
when 's'
|
75
|
-
when nil
|
82
|
+
when 'xl' then %(#{brand}-label--xl)
|
83
|
+
when 'l' then %(#{brand}-label--l)
|
84
|
+
when 'm' then %(#{brand}-label--m)
|
85
|
+
when 's' then %(#{brand}-label--s)
|
86
|
+
when nil then nil
|
76
87
|
else
|
77
88
|
fail "invalid size '#{size}', must be xl, l, m, s or nil"
|
78
89
|
end
|