govuk_design_system_formbuilder 1.1.11 → 1.2.1
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/README.md +2 -2
- data/lib/govuk_design_system_formbuilder.rb +7 -1
- data/lib/govuk_design_system_formbuilder/base.rb +17 -0
- data/lib/govuk_design_system_formbuilder/builder.rb +205 -77
- data/lib/govuk_design_system_formbuilder/containers/character_count.rb +2 -2
- data/lib/govuk_design_system_formbuilder/containers/check_boxes.rb +5 -3
- data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +12 -11
- data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +37 -20
- data/lib/govuk_design_system_formbuilder/containers/form_group.rb +4 -2
- data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +12 -11
- data/lib/govuk_design_system_formbuilder/containers/radios.rb +7 -5
- data/lib/govuk_design_system_formbuilder/elements/caption.rb +34 -0
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +11 -13
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +20 -16
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +24 -29
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/label.rb +3 -1
- data/lib/govuk_design_system_formbuilder/elements/date.rb +31 -31
- data/lib/govuk_design_system_formbuilder/elements/error_message.rb +11 -8
- data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +26 -29
- data/lib/govuk_design_system_formbuilder/elements/file.rb +22 -21
- data/lib/govuk_design_system_formbuilder/elements/hint.rb +6 -7
- data/lib/govuk_design_system_formbuilder/elements/inputs/email.rb +2 -0
- data/lib/govuk_design_system_formbuilder/elements/inputs/number.rb +2 -0
- data/lib/govuk_design_system_formbuilder/elements/inputs/password.rb +2 -0
- data/lib/govuk_design_system_formbuilder/elements/inputs/phone.rb +2 -0
- data/lib/govuk_design_system_formbuilder/elements/inputs/text.rb +2 -0
- data/lib/govuk_design_system_formbuilder/elements/inputs/url.rb +2 -0
- data/lib/govuk_design_system_formbuilder/elements/label.rb +39 -26
- data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +26 -24
- data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +16 -14
- data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +19 -21
- data/lib/govuk_design_system_formbuilder/elements/select.rb +12 -20
- data/lib/govuk_design_system_formbuilder/elements/submit.rb +29 -27
- data/lib/govuk_design_system_formbuilder/elements/text_area.rb +27 -27
- data/lib/govuk_design_system_formbuilder/traits/caption.rb +23 -0
- data/lib/govuk_design_system_formbuilder/traits/input.rb +33 -41
- data/lib/govuk_design_system_formbuilder/traits/label.rb +12 -1
- data/lib/govuk_design_system_formbuilder/traits/localisation.rb +2 -0
- data/lib/govuk_design_system_formbuilder/version.rb +1 -1
- metadata +19 -17
@@ -2,6 +2,8 @@ module GOVUKDesignSystemFormBuilder
|
|
2
2
|
module Elements
|
3
3
|
module CheckBoxes
|
4
4
|
class Label < Base
|
5
|
+
using PrefixableArray
|
6
|
+
|
5
7
|
include Traits::Localisation
|
6
8
|
|
7
9
|
def initialize(builder, object_name, attribute_name, checkbox, value:, link_errors: true)
|
@@ -21,7 +23,7 @@ module GOVUKDesignSystemFormBuilder
|
|
21
23
|
private
|
22
24
|
|
23
25
|
def label_classes
|
24
|
-
%w(
|
26
|
+
%w(label checkboxes__label).prefix(brand)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -1,16 +1,19 @@
|
|
1
1
|
module GOVUKDesignSystemFormBuilder
|
2
2
|
module Elements
|
3
3
|
class Date < Base
|
4
|
+
using PrefixableArray
|
5
|
+
|
4
6
|
include Traits::Error
|
5
7
|
include Traits::Hint
|
6
8
|
include Traits::Supplemental
|
7
9
|
|
8
10
|
SEGMENTS = { day: '3i', month: '2i', year: '1i' }.freeze
|
9
11
|
|
10
|
-
def initialize(builder, object_name, attribute_name, legend:, 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:, &block)
|
11
13
|
super(builder, object_name, attribute_name, &block)
|
12
14
|
|
13
15
|
@legend = legend
|
16
|
+
@caption = caption
|
14
17
|
@hint_text = hint_text
|
15
18
|
@date_of_birth = date_of_birth
|
16
19
|
@omit_day = omit_day
|
@@ -18,23 +21,20 @@ module GOVUKDesignSystemFormBuilder
|
|
18
21
|
|
19
22
|
def html
|
20
23
|
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
21
|
-
Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, described_by: [error_id, hint_id, supplemental_id]).html do
|
22
|
-
safe_join(
|
23
|
-
[
|
24
|
-
supplemental_content.html,
|
25
|
-
hint_element.html,
|
26
|
-
error_element.html,
|
27
|
-
content_tag('div', class: 'govuk-date-input') do
|
28
|
-
safe_join([day, month, year])
|
29
|
-
end
|
30
|
-
]
|
31
|
-
)
|
24
|
+
Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id]).html do
|
25
|
+
safe_join([supplemental_content, hint_element, error_element, date])
|
32
26
|
end
|
33
27
|
end
|
34
28
|
end
|
35
29
|
|
36
30
|
private
|
37
31
|
|
32
|
+
def date
|
33
|
+
content_tag('div', class: %(#{brand}-date-input)) do
|
34
|
+
safe_join([day, month, year])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
38
|
def omit_day?
|
39
39
|
@omit_day
|
40
40
|
end
|
@@ -42,34 +42,34 @@ module GOVUKDesignSystemFormBuilder
|
|
42
42
|
def day
|
43
43
|
return nil if omit_day?
|
44
44
|
|
45
|
-
|
45
|
+
date_part_input(:day, link_errors: true)
|
46
46
|
end
|
47
47
|
|
48
48
|
def month
|
49
|
-
|
49
|
+
date_part_input(:month, link_errors: omit_day?)
|
50
50
|
end
|
51
51
|
|
52
52
|
def year
|
53
|
-
|
53
|
+
date_part_input(:year, width: 4)
|
54
54
|
end
|
55
55
|
|
56
|
-
def
|
56
|
+
def date_part_input(segment, width: 2, link_errors: false)
|
57
57
|
value = @builder.object.try(@attribute_name).try(segment)
|
58
58
|
|
59
|
-
content_tag('div', class: %w(
|
60
|
-
content_tag('div', class: %w(
|
59
|
+
content_tag('div', class: %w(date-input__item).prefix(brand)) do
|
60
|
+
content_tag('div', class: %w(form-group).prefix(brand)) do
|
61
61
|
safe_join(
|
62
62
|
[
|
63
63
|
tag.label(
|
64
64
|
segment.capitalize,
|
65
|
-
class:
|
66
|
-
for:
|
65
|
+
class: date_part_label_classes,
|
66
|
+
for: date_part_attribute_id(segment, link_errors)
|
67
67
|
),
|
68
68
|
|
69
69
|
tag.input(
|
70
|
-
id:
|
71
|
-
class:
|
72
|
-
name:
|
70
|
+
id: date_part_attribute_id(segment, link_errors),
|
71
|
+
class: date_part_input_classes(width),
|
72
|
+
name: date_part_attribute_name(segment),
|
73
73
|
type: 'text',
|
74
74
|
pattern: '[0-9]*',
|
75
75
|
inputmode: 'numeric',
|
@@ -82,21 +82,21 @@ module GOVUKDesignSystemFormBuilder
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
-
def
|
86
|
-
%w(
|
87
|
-
classes.push(
|
88
|
-
classes.push(
|
85
|
+
def date_part_input_classes(width)
|
86
|
+
%w(input date-input__input).prefix(brand).tap do |classes|
|
87
|
+
classes.push(%(#{brand}-input--width-#{width}))
|
88
|
+
classes.push(%(#{brand}-input--error)) if has_errors?
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
def
|
93
|
-
%w(
|
92
|
+
def date_part_label_classes
|
93
|
+
%w(label date-input__label).prefix(brand)
|
94
94
|
end
|
95
95
|
|
96
96
|
# if the field has errors we want the govuk_error_summary to
|
97
97
|
# be able to link to the day field. Otherwise, generate IDs
|
98
98
|
# in the normal fashion
|
99
|
-
def
|
99
|
+
def date_part_attribute_id(segment, link_errors)
|
100
100
|
if has_errors? && link_errors
|
101
101
|
field_id(link_errors: link_errors)
|
102
102
|
else
|
@@ -104,7 +104,7 @@ module GOVUKDesignSystemFormBuilder
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
def
|
107
|
+
def date_part_attribute_name(segment)
|
108
108
|
format(
|
109
109
|
"%<object_name>s[%<attribute_name>s(%<segment>s)]",
|
110
110
|
object_name: @object_name,
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module GOVUKDesignSystemFormBuilder
|
2
2
|
module Elements
|
3
3
|
class ErrorMessage < Base
|
4
|
+
using PrefixableArray
|
5
|
+
|
4
6
|
include Traits::Error
|
5
7
|
|
6
8
|
def initialize(builder, object_name, attribute_name)
|
@@ -10,17 +12,18 @@ module GOVUKDesignSystemFormBuilder
|
|
10
12
|
def html
|
11
13
|
return nil unless has_errors?
|
12
14
|
|
13
|
-
content_tag('span', class:
|
14
|
-
safe_join(
|
15
|
-
[
|
16
|
-
tag.span('Error: ', class: 'govuk-visually-hidden'),
|
17
|
-
message
|
18
|
-
]
|
19
|
-
)
|
15
|
+
content_tag('span', class: %(#{brand}-error-message), id: error_id) do
|
16
|
+
safe_join([error_prefix, error_message])
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
23
|
-
|
20
|
+
private
|
21
|
+
|
22
|
+
def error_prefix
|
23
|
+
tag.span('Error: ', class: %(#{brand}-visually-hidden))
|
24
|
+
end
|
25
|
+
|
26
|
+
def error_message
|
24
27
|
@builder.object.errors.messages[@attribute_name]&.first
|
25
28
|
end
|
26
29
|
end
|
@@ -12,47 +12,44 @@ module GOVUKDesignSystemFormBuilder
|
|
12
12
|
def html
|
13
13
|
return nil unless object_has_errors?
|
14
14
|
|
15
|
-
content_tag('div', 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: ['govuk-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: error_summary_class, **error_summary_options) do
|
16
|
+
safe_join([error_title, error_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 error_title
|
23
|
+
tag.h2(@title, id: error_summary_title_id, class: error_summary_class('title'))
|
24
|
+
end
|
25
|
+
|
26
|
+
def error_summary
|
27
|
+
content_tag('div', class: error_summary_class('body')) do
|
28
|
+
content_tag('ul', class: [%(#{brand}-list), error_summary_class('list')]) do
|
29
|
+
safe_join(error_list)
|
30
|
+
end
|
44
31
|
end
|
45
32
|
end
|
46
33
|
|
34
|
+
def error_list
|
35
|
+
@builder.object.errors.messages.map do |attribute, messages|
|
36
|
+
error_list_item(attribute, messages.first)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def error_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
|
50
47
|
|
51
|
-
def
|
48
|
+
def error_summary_class(part = nil)
|
52
49
|
if part
|
53
|
-
|
50
|
+
%(#{brand}-error-summary).concat('__', part)
|
54
51
|
else
|
55
|
-
|
52
|
+
%(#{brand}-error-summary)
|
56
53
|
end
|
57
54
|
end
|
58
55
|
|
@@ -68,12 +65,12 @@ module GOVUKDesignSystemFormBuilder
|
|
68
65
|
@builder.object.errors.any?
|
69
66
|
end
|
70
67
|
|
71
|
-
def
|
68
|
+
def error_summary_options
|
72
69
|
{
|
73
70
|
tabindex: -1,
|
74
71
|
role: 'alert',
|
75
72
|
data: {
|
76
|
-
module:
|
73
|
+
module: %(#{brand}-error-summary)
|
77
74
|
},
|
78
75
|
aria: {
|
79
76
|
labelledby: error_summary_title_id
|
@@ -1,44 +1,45 @@
|
|
1
1
|
module GOVUKDesignSystemFormBuilder
|
2
2
|
module Elements
|
3
3
|
class File < Base
|
4
|
+
using PrefixableArray
|
5
|
+
|
4
6
|
include Traits::Error
|
5
7
|
include Traits::Hint
|
6
8
|
include Traits::Label
|
7
9
|
include Traits::Supplemental
|
8
10
|
|
9
|
-
def initialize(builder, object_name, attribute_name, hint_text:, label:, **
|
11
|
+
def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, **kwargs, &block)
|
10
12
|
super(builder, object_name, attribute_name, &block)
|
11
13
|
|
12
|
-
@label
|
13
|
-
@
|
14
|
-
@
|
14
|
+
@label = label
|
15
|
+
@caption = caption
|
16
|
+
@hint_text = hint_text
|
17
|
+
@extra_options = kwargs
|
15
18
|
end
|
16
19
|
|
17
20
|
def html
|
18
21
|
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
19
|
-
safe_join(
|
20
|
-
[
|
21
|
-
label_element.html,
|
22
|
-
supplemental_content.html,
|
23
|
-
hint_element.html,
|
24
|
-
error_element.html,
|
25
|
-
@builder.file_field(
|
26
|
-
@attribute_name,
|
27
|
-
id: field_id(link_errors: true),
|
28
|
-
class: file_classes,
|
29
|
-
aria: { describedby: described_by(hint_id, error_id, supplemental_id) },
|
30
|
-
**@extra_args
|
31
|
-
)
|
32
|
-
]
|
33
|
-
)
|
22
|
+
safe_join([label_element, supplemental_content, hint_element, error_element, file])
|
34
23
|
end
|
35
24
|
end
|
36
25
|
|
37
26
|
private
|
38
27
|
|
28
|
+
def file
|
29
|
+
@builder.file_field(@attribute_name, **file_options, **@extra_options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def file_options
|
33
|
+
{
|
34
|
+
id: field_id(link_errors: true),
|
35
|
+
class: file_classes,
|
36
|
+
aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
39
40
|
def file_classes
|
40
|
-
%w(
|
41
|
-
c.push(
|
41
|
+
%w(file-upload).prefix(brand).tap do |c|
|
42
|
+
c.push(%(#{brand}-file-upload--error)) if has_errors?
|
42
43
|
end
|
43
44
|
end
|
44
45
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module GOVUKDesignSystemFormBuilder
|
2
2
|
module Elements
|
3
3
|
class Hint < Base
|
4
|
+
using PrefixableArray
|
5
|
+
|
4
6
|
include Traits::Hint
|
5
7
|
include Traits::Localisation
|
6
8
|
|
@@ -22,22 +24,19 @@ module GOVUKDesignSystemFormBuilder
|
|
22
24
|
private
|
23
25
|
|
24
26
|
def hint_text(supplied)
|
25
|
-
[
|
26
|
-
supplied.presence,
|
27
|
-
localised_text(:hint)
|
28
|
-
].compact.first
|
27
|
+
[supplied.presence, localised_text(:hint)].compact.first
|
29
28
|
end
|
30
29
|
|
31
30
|
def hint_classes
|
32
|
-
%w(
|
31
|
+
%w(hint).prefix(brand).push(@radio_class, @checkbox_class).compact
|
33
32
|
end
|
34
33
|
|
35
34
|
def radio_class(radio)
|
36
|
-
radio ?
|
35
|
+
radio ? %(#{brand}-radios__hint) : nil
|
37
36
|
end
|
38
37
|
|
39
38
|
def checkbox_class(checkbox)
|
40
|
-
checkbox ?
|
39
|
+
checkbox ? %(#{brand}-checkboxes__hint) : nil
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
@@ -1,40 +1,45 @@
|
|
1
1
|
module GOVUKDesignSystemFormBuilder
|
2
2
|
module Elements
|
3
3
|
class Label < Base
|
4
|
+
using PrefixableArray
|
5
|
+
|
6
|
+
include Traits::Caption
|
4
7
|
include Traits::Localisation
|
5
8
|
|
6
|
-
def initialize(builder, object_name, attribute_name, text: nil, value: nil, size: nil, hidden: false, radio: false, checkbox: false, tag: nil, link_errors: true)
|
9
|
+
def initialize(builder, object_name, attribute_name, text: nil, value: nil, size: nil, hidden: false, radio: false, checkbox: false, tag: nil, link_errors: true, content: nil, caption: nil)
|
7
10
|
super(builder, object_name, attribute_name)
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
# content is passed in directly via a proc and overrides
|
13
|
+
# the other display options
|
14
|
+
if content
|
15
|
+
@content = content.call
|
16
|
+
else
|
17
|
+
@value = value # used by field_id
|
18
|
+
@text = label_text(text, hidden)
|
19
|
+
@size_class = label_size_class(size)
|
20
|
+
@radio_class = radio_class(radio)
|
21
|
+
@checkbox_class = checkbox_class(checkbox)
|
22
|
+
@tag = tag
|
23
|
+
@link_errors = link_errors
|
24
|
+
@caption = caption
|
25
|
+
end
|
16
26
|
end
|
17
27
|
|
18
28
|
def html
|
19
|
-
return nil if @text.blank?
|
29
|
+
return nil if [@content, @text].all?(&:blank?)
|
20
30
|
|
21
31
|
if @tag.present?
|
22
|
-
content_tag(@tag, class:
|
32
|
+
content_tag(@tag, class: %(#{brand}-label-wrapper)) { label }
|
23
33
|
else
|
24
|
-
|
34
|
+
label
|
25
35
|
end
|
26
36
|
end
|
27
37
|
|
28
38
|
private
|
29
39
|
|
30
|
-
def
|
31
|
-
@builder.label(
|
32
|
-
@
|
33
|
-
value: @value,
|
34
|
-
for: field_id(link_errors: @link_errors),
|
35
|
-
class: %w(govuk-label).push(@size_class, @weight_class, @radio_class, @checkbox_class).compact
|
36
|
-
) do
|
37
|
-
@text
|
40
|
+
def label
|
41
|
+
@builder.label(@attribute_name, label_options) do
|
42
|
+
@content || safe_join([caption_element.html, @text])
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
@@ -42,26 +47,34 @@ module GOVUKDesignSystemFormBuilder
|
|
42
47
|
text = [option_text, localised_text(:label), @attribute_name.capitalize].compact.first.to_s
|
43
48
|
|
44
49
|
if hidden
|
45
|
-
tag.span(text, class: %w(
|
50
|
+
tag.span(text, class: %w(visually-hidden).prefix(brand))
|
46
51
|
else
|
47
52
|
text
|
48
53
|
end
|
49
54
|
end
|
50
55
|
|
56
|
+
def label_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
|
+
|
51
64
|
def radio_class(radio)
|
52
|
-
radio ?
|
65
|
+
radio ? %(#{brand}-radios__label) : nil
|
53
66
|
end
|
54
67
|
|
55
68
|
def checkbox_class(checkbox)
|
56
|
-
checkbox ?
|
69
|
+
checkbox ? %(#{brand}-checkboxes__label) : nil
|
57
70
|
end
|
58
71
|
|
59
72
|
def label_size_class(size)
|
60
73
|
case size
|
61
|
-
when 'xl' then
|
62
|
-
when 'l' then
|
63
|
-
when 'm' then
|
64
|
-
when 's' then
|
74
|
+
when 'xl' then %(#{brand}-label--xl)
|
75
|
+
when 'l' then %(#{brand}-label--l)
|
76
|
+
when 'm' then %(#{brand}-label--m)
|
77
|
+
when 's' then %(#{brand}-label--s)
|
65
78
|
when nil then nil
|
66
79
|
else
|
67
80
|
fail "invalid size '#{size}', must be xl, l, m, s or nil"
|