govuk_design_system_formbuilder 1.2.3 → 2.0.0b1
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 +1 -1
- data/lib/govuk_design_system_formbuilder/base.rb +1 -1
- data/lib/govuk_design_system_formbuilder/builder.rb +155 -60
- 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 +13 -4
- data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +15 -55
- data/lib/govuk_design_system_formbuilder/containers/form_group.rb +19 -10
- data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +13 -4
- 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 +6 -4
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +21 -12
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +9 -7
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +24 -16
- data/lib/govuk_design_system_formbuilder/elements/date.rb +47 -40
- data/lib/govuk_design_system_formbuilder/elements/error_message.rb +4 -4
- data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +15 -15
- data/lib/govuk_design_system_formbuilder/elements/file.rb +8 -7
- data/lib/govuk_design_system_formbuilder/elements/hint.rb +43 -16
- data/lib/govuk_design_system_formbuilder/elements/inputs/email.rb +2 -2
- data/lib/govuk_design_system_formbuilder/elements/inputs/number.rb +0 -2
- data/lib/govuk_design_system_formbuilder/elements/inputs/password.rb +0 -2
- data/lib/govuk_design_system_formbuilder/elements/inputs/phone.rb +0 -2
- data/lib/govuk_design_system_formbuilder/elements/inputs/text.rb +0 -2
- data/lib/govuk_design_system_formbuilder/elements/inputs/url.rb +0 -2
- data/lib/govuk_design_system_formbuilder/elements/label.rb +35 -27
- data/lib/govuk_design_system_formbuilder/elements/legend.rb +79 -0
- data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +23 -14
- data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +24 -8
- data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +19 -7
- data/lib/govuk_design_system_formbuilder/elements/select.rb +24 -19
- data/lib/govuk_design_system_formbuilder/elements/submit.rb +11 -6
- data/lib/govuk_design_system_formbuilder/elements/text_area.rb +31 -25
- data/lib/govuk_design_system_formbuilder/traits/collection_item.rb +1 -1
- data/lib/govuk_design_system_formbuilder/traits/conditional.rb +1 -1
- data/lib/govuk_design_system_formbuilder/traits/hint.rb +15 -2
- data/lib/govuk_design_system_formbuilder/traits/input.rb +9 -8
- data/lib/govuk_design_system_formbuilder/traits/label.rb +2 -2
- data/lib/govuk_design_system_formbuilder/version.rb +1 -1
- metadata +11 -10
@@ -8,12 +8,12 @@ module GOVUKDesignSystemFormBuilder
|
|
8
8
|
include Traits::Hint
|
9
9
|
include Traits::Conditional
|
10
10
|
|
11
|
-
def initialize(builder, object_name, attribute_name, value, label:,
|
11
|
+
def initialize(builder, object_name, attribute_name, value, label:, hint:, link_errors:, multiple:, &block)
|
12
12
|
super(builder, object_name, attribute_name)
|
13
13
|
|
14
14
|
@value = value
|
15
15
|
@label = label
|
16
|
-
@
|
16
|
+
@hint = hint
|
17
17
|
@multiple = multiple
|
18
18
|
@link_errors = link_errors
|
19
19
|
|
@@ -24,45 +24,53 @@ module GOVUKDesignSystemFormBuilder
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def html
|
27
|
-
safe_join([
|
27
|
+
safe_join([item, @conditional_content])
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
-
def
|
33
|
-
|
34
|
-
safe_join([
|
32
|
+
def item
|
33
|
+
tag.div(class: %(#{brand}-checkboxes__item)) do
|
34
|
+
safe_join([check_box, label_element, hint_element])
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
@builder.check_box(@attribute_name,
|
38
|
+
def check_box
|
39
|
+
@builder.check_box(@attribute_name, options, @value, false)
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
42
|
+
def options
|
43
43
|
{
|
44
44
|
id: field_id(link_errors: @link_errors),
|
45
|
-
class:
|
45
|
+
class: classes,
|
46
46
|
multiple: @multiple,
|
47
47
|
aria: { describedby: hint_id },
|
48
48
|
data: { 'aria-controls' => @conditional_id }
|
49
49
|
}
|
50
50
|
end
|
51
51
|
|
52
|
+
def classes
|
53
|
+
%w(checkboxes__input).prefix(brand)
|
54
|
+
end
|
55
|
+
|
52
56
|
def label_element
|
53
|
-
@label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name,
|
57
|
+
@label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, **label_content, **label_options)
|
58
|
+
end
|
59
|
+
|
60
|
+
def label_options
|
61
|
+
{ checkbox: true, value: @value, link_errors: @link_errors }
|
54
62
|
end
|
55
63
|
|
56
64
|
def hint_element
|
57
|
-
@hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name,
|
65
|
+
@hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, **hint_options, **hint_content)
|
58
66
|
end
|
59
67
|
|
60
|
-
def
|
61
|
-
|
68
|
+
def hint_options
|
69
|
+
{ checkbox: true }
|
62
70
|
end
|
63
71
|
|
64
|
-
def
|
65
|
-
%w(
|
72
|
+
def conditional_classes
|
73
|
+
%w(checkboxes__conditional checkboxes__conditional--hidden).prefix(brand)
|
66
74
|
end
|
67
75
|
end
|
68
76
|
end
|
@@ -9,19 +9,20 @@ 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:,
|
12
|
+
def initialize(builder, object_name, attribute_name, legend:, caption:, hint:, date_of_birth: false, omit_day:, form_group:, &block)
|
13
13
|
super(builder, object_name, attribute_name, &block)
|
14
14
|
|
15
15
|
@legend = legend
|
16
16
|
@caption = caption
|
17
|
-
@
|
17
|
+
@hint = hint
|
18
18
|
@date_of_birth = date_of_birth
|
19
19
|
@omit_day = omit_day
|
20
|
+
@form_group = form_group
|
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,
|
24
|
+
Containers::FormGroup.new(@builder, @object_name, @attribute_name, **@form_group).html do
|
25
|
+
Containers::Fieldset.new(@builder, @object_name, @attribute_name, **fieldset_options).html do
|
25
26
|
safe_join([supplemental_content, hint_element, error_element, date])
|
26
27
|
end
|
27
28
|
end
|
@@ -29,8 +30,12 @@ module GOVUKDesignSystemFormBuilder
|
|
29
30
|
|
30
31
|
private
|
31
32
|
|
33
|
+
def fieldset_options
|
34
|
+
{ legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id] }
|
35
|
+
end
|
36
|
+
|
32
37
|
def date
|
33
|
-
|
38
|
+
tag.div(class: %(#{brand}-date-input)) do
|
34
39
|
safe_join([day, month, year])
|
35
40
|
end
|
36
41
|
end
|
@@ -42,61 +47,59 @@ module GOVUKDesignSystemFormBuilder
|
|
42
47
|
def day
|
43
48
|
return nil if omit_day?
|
44
49
|
|
45
|
-
|
50
|
+
date_part(:day, width: 2, link_errors: true)
|
46
51
|
end
|
47
52
|
|
48
53
|
def month
|
49
|
-
|
54
|
+
date_part(:month, width: 2, link_errors: omit_day?)
|
50
55
|
end
|
51
56
|
|
52
57
|
def year
|
53
|
-
|
58
|
+
date_part(:year, width: 4)
|
54
59
|
end
|
55
60
|
|
56
|
-
def
|
61
|
+
def date_part(segment, width:, link_errors: false)
|
57
62
|
value = @builder.object.try(@attribute_name).try(segment)
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
safe_join(
|
62
|
-
[
|
63
|
-
tag.label(
|
64
|
-
segment.capitalize,
|
65
|
-
class: date_part_label_classes,
|
66
|
-
for: date_part_attribute_id(segment, link_errors)
|
67
|
-
),
|
68
|
-
|
69
|
-
tag.input(
|
70
|
-
id: date_part_attribute_id(segment, link_errors),
|
71
|
-
class: date_part_input_classes(width),
|
72
|
-
name: date_part_attribute_name(segment),
|
73
|
-
type: 'text',
|
74
|
-
pattern: '[0-9]*',
|
75
|
-
inputmode: 'numeric',
|
76
|
-
value: value,
|
77
|
-
autocomplete: date_of_birth_autocomplete_value(segment)
|
78
|
-
)
|
79
|
-
]
|
80
|
-
)
|
64
|
+
tag.div(class: %(#{brand}-date-input__item)) do
|
65
|
+
tag.div(class: %(#{brand}-form-group)) do
|
66
|
+
safe_join([label(segment, link_errors), input(segment, link_errors, width, value)])
|
81
67
|
end
|
82
68
|
end
|
83
69
|
end
|
84
70
|
|
85
|
-
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)
|
86
93
|
%w(input date-input__input).prefix(brand).tap do |classes|
|
87
94
|
classes.push(%(#{brand}-input--width-#{width}))
|
88
95
|
classes.push(%(#{brand}-input--error)) if has_errors?
|
89
96
|
end
|
90
97
|
end
|
91
98
|
|
92
|
-
def date_part_label_classes
|
93
|
-
%w(label date-input__label).prefix(brand)
|
94
|
-
end
|
95
|
-
|
96
99
|
# if the field has errors we want the govuk_error_summary to
|
97
100
|
# be able to link to the day field. Otherwise, generate IDs
|
98
101
|
# in the normal fashion
|
99
|
-
def
|
102
|
+
def id(segment, link_errors)
|
100
103
|
if has_errors? && link_errors
|
101
104
|
field_id(link_errors: link_errors)
|
102
105
|
else
|
@@ -104,11 +107,11 @@ module GOVUKDesignSystemFormBuilder
|
|
104
107
|
end
|
105
108
|
end
|
106
109
|
|
107
|
-
def
|
110
|
+
def name(segment)
|
108
111
|
format(
|
109
|
-
"%<object_name>s[%<
|
112
|
+
"%<object_name>s[%<input_name>s(%<segment>s)]",
|
110
113
|
object_name: @object_name,
|
111
|
-
|
114
|
+
input_name: @attribute_name,
|
112
115
|
segment: SEGMENTS.fetch(segment)
|
113
116
|
)
|
114
117
|
end
|
@@ -118,6 +121,10 @@ module GOVUKDesignSystemFormBuilder
|
|
118
121
|
|
119
122
|
{ day: 'bday-day', month: 'bday-month', year: 'bday-year' }.fetch(segment)
|
120
123
|
end
|
124
|
+
|
125
|
+
def label_classes
|
126
|
+
%w(label date-input__label).prefix(brand)
|
127
|
+
end
|
121
128
|
end
|
122
129
|
end
|
123
130
|
end
|
@@ -12,18 +12,18 @@ module GOVUKDesignSystemFormBuilder
|
|
12
12
|
def html
|
13
13
|
return nil unless has_errors?
|
14
14
|
|
15
|
-
|
16
|
-
safe_join([
|
15
|
+
tag.span(class: %(#{brand}-error-message), id: error_id) do
|
16
|
+
safe_join([hidden_prefix, message])
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
|
-
def
|
22
|
+
def hidden_prefix
|
23
23
|
tag.span('Error: ', class: %(#{brand}-visually-hidden))
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def message
|
27
27
|
@builder.object.errors.messages[@attribute_name]&.first
|
28
28
|
end
|
29
29
|
end
|
@@ -12,32 +12,32 @@ module GOVUKDesignSystemFormBuilder
|
|
12
12
|
def html
|
13
13
|
return nil unless object_has_errors?
|
14
14
|
|
15
|
-
|
16
|
-
safe_join([
|
15
|
+
tag.div(class: summary_class, **summary_options) do
|
16
|
+
safe_join([title, summary])
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
|
-
def
|
23
|
-
tag.h2(@title, id:
|
22
|
+
def title
|
23
|
+
tag.h2(@title, id: summary_title_id, class: summary_class('title'))
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
safe_join(
|
26
|
+
def summary
|
27
|
+
tag.div(class: summary_class('body')) do
|
28
|
+
tag.ul(class: [%(#{brand}-list), summary_class('list')]) do
|
29
|
+
safe_join(list)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
34
|
+
def list
|
35
35
|
@builder.object.errors.messages.map do |attribute, messages|
|
36
|
-
|
36
|
+
list_item(attribute, messages.first)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
40
|
+
def list_item(attribute, message)
|
41
41
|
tag.li(link_to(message, same_page_link(field_id(attribute)), data: { turbolinks: false }))
|
42
42
|
end
|
43
43
|
|
@@ -45,7 +45,7 @@ module GOVUKDesignSystemFormBuilder
|
|
45
45
|
'#'.concat(target)
|
46
46
|
end
|
47
47
|
|
48
|
-
def
|
48
|
+
def summary_class(part = nil)
|
49
49
|
if part
|
50
50
|
%(#{brand}-error-summary).concat('__', part)
|
51
51
|
else
|
@@ -57,7 +57,7 @@ module GOVUKDesignSystemFormBuilder
|
|
57
57
|
build_id('field-error', attribute_name: attribute)
|
58
58
|
end
|
59
59
|
|
60
|
-
def
|
60
|
+
def summary_title_id
|
61
61
|
'error-summary-title'
|
62
62
|
end
|
63
63
|
|
@@ -65,7 +65,7 @@ module GOVUKDesignSystemFormBuilder
|
|
65
65
|
@builder.object.errors.any?
|
66
66
|
end
|
67
67
|
|
68
|
-
def
|
68
|
+
def summary_options
|
69
69
|
{
|
70
70
|
tabindex: -1,
|
71
71
|
role: 'alert',
|
@@ -73,7 +73,7 @@ module GOVUKDesignSystemFormBuilder
|
|
73
73
|
module: %(#{brand}-error-summary)
|
74
74
|
},
|
75
75
|
aria: {
|
76
|
-
labelledby:
|
76
|
+
labelledby: summary_title_id
|
77
77
|
}
|
78
78
|
}
|
79
79
|
end
|
@@ -8,17 +8,18 @@ module GOVUKDesignSystemFormBuilder
|
|
8
8
|
include Traits::Label
|
9
9
|
include Traits::Supplemental
|
10
10
|
|
11
|
-
def initialize(builder, object_name, attribute_name,
|
11
|
+
def initialize(builder, object_name, attribute_name, hint:, label:, caption:, form_group:, **kwargs, &block)
|
12
12
|
super(builder, object_name, attribute_name, &block)
|
13
13
|
|
14
14
|
@label = label
|
15
15
|
@caption = caption
|
16
|
-
@
|
16
|
+
@hint = hint
|
17
17
|
@extra_options = kwargs
|
18
|
+
@form_group = form_group
|
18
19
|
end
|
19
20
|
|
20
21
|
def html
|
21
|
-
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
22
|
+
Containers::FormGroup.new(@builder, @object_name, @attribute_name, **@form_group).html do
|
22
23
|
safe_join([label_element, supplemental_content, hint_element, error_element, file])
|
23
24
|
end
|
24
25
|
end
|
@@ -26,18 +27,18 @@ module GOVUKDesignSystemFormBuilder
|
|
26
27
|
private
|
27
28
|
|
28
29
|
def file
|
29
|
-
@builder.file_field(@attribute_name, **
|
30
|
+
@builder.file_field(@attribute_name, **options, **@extra_options)
|
30
31
|
end
|
31
32
|
|
32
|
-
def
|
33
|
+
def options
|
33
34
|
{
|
34
35
|
id: field_id(link_errors: true),
|
35
|
-
class:
|
36
|
+
class: classes,
|
36
37
|
aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
|
37
38
|
}
|
38
39
|
end
|
39
40
|
|
40
|
-
def
|
41
|
+
def classes
|
41
42
|
%w(file-upload).prefix(brand).tap do |c|
|
42
43
|
c.push(%(#{brand}-file-upload--error)) if has_errors?
|
43
44
|
end
|
@@ -3,40 +3,67 @@ module GOVUKDesignSystemFormBuilder
|
|
3
3
|
class Hint < Base
|
4
4
|
using PrefixableArray
|
5
5
|
|
6
|
-
include Traits::Hint
|
7
6
|
include Traits::Localisation
|
8
7
|
|
9
|
-
def initialize(builder, object_name, attribute_name, text,
|
8
|
+
def initialize(builder, object_name, attribute_name, value: nil, text: nil, content: nil, radio: false, checkbox: false, **kwargs)
|
10
9
|
super(builder, object_name, attribute_name)
|
11
10
|
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
15
|
-
|
11
|
+
@radio = radio
|
12
|
+
@checkbox = checkbox
|
13
|
+
@html_attributes = kwargs
|
14
|
+
|
15
|
+
if content
|
16
|
+
@content = capture { content.call }
|
17
|
+
else
|
18
|
+
@text = retrieve_text(text)
|
19
|
+
@value = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def active?
|
24
|
+
[@text, @content].any?(&:present?)
|
16
25
|
end
|
17
26
|
|
18
27
|
def html
|
19
|
-
return nil
|
28
|
+
return nil unless active?
|
29
|
+
|
30
|
+
content_tag(hint_tag, **hint_options, **@html_attributes) { hint_body }
|
31
|
+
end
|
32
|
+
|
33
|
+
def hint_id
|
34
|
+
return nil unless active?
|
20
35
|
|
21
|
-
|
36
|
+
build_id('hint')
|
22
37
|
end
|
23
38
|
|
24
39
|
private
|
25
40
|
|
26
|
-
def
|
27
|
-
|
41
|
+
def hint_options
|
42
|
+
{ class: classes, id: hint_id }
|
43
|
+
end
|
44
|
+
|
45
|
+
def hint_tag
|
46
|
+
@content.presence ? 'div' : 'span'
|
47
|
+
end
|
48
|
+
|
49
|
+
def hint_body
|
50
|
+
@content || @text
|
51
|
+
end
|
52
|
+
|
53
|
+
def retrieve_text(supplied)
|
54
|
+
supplied.presence || localised_text(:hint)
|
28
55
|
end
|
29
56
|
|
30
|
-
def
|
31
|
-
%w(hint).prefix(brand).push(
|
57
|
+
def classes
|
58
|
+
%w(hint).prefix(brand).push(radio_class, checkbox_class).compact
|
32
59
|
end
|
33
60
|
|
34
|
-
def radio_class
|
35
|
-
radio ? %(#{brand}-radios__hint) : nil
|
61
|
+
def radio_class
|
62
|
+
@radio ? %(#{brand}-radios__hint) : nil
|
36
63
|
end
|
37
64
|
|
38
|
-
def checkbox_class
|
39
|
-
checkbox ? %(#{brand}-checkboxes__hint) : nil
|
65
|
+
def checkbox_class
|
66
|
+
@checkbox ? %(#{brand}-checkboxes__hint) : nil
|
40
67
|
end
|
41
68
|
end
|
42
69
|
end
|