govuk_design_system_formbuilder 0.7.9 → 0.7.10
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 +52 -18
- data/lib/govuk_design_system_formbuilder.rb +19 -4
- data/lib/govuk_design_system_formbuilder/base.rb +54 -17
- data/lib/govuk_design_system_formbuilder/builder.rb +147 -93
- data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +28 -0
- data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +3 -9
- data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +29 -0
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +62 -0
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +21 -7
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +75 -0
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/hint.rb +9 -17
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/label.rb +5 -4
- data/lib/govuk_design_system_formbuilder/elements/date.rb +18 -14
- data/lib/govuk_design_system_formbuilder/elements/error_message.rb +6 -4
- data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +23 -8
- data/lib/govuk_design_system_formbuilder/elements/file.rb +40 -0
- data/lib/govuk_design_system_formbuilder/elements/hint.rb +1 -1
- data/lib/govuk_design_system_formbuilder/elements/input.rb +4 -12
- data/lib/govuk_design_system_formbuilder/elements/label.rb +16 -6
- data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +55 -0
- data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +48 -0
- data/lib/govuk_design_system_formbuilder/elements/radios/{fieldset_radio.rb → fieldset_radio_button.rb} +17 -8
- data/lib/govuk_design_system_formbuilder/elements/select.rb +51 -0
- data/lib/govuk_design_system_formbuilder/elements/submit.rb +21 -13
- data/lib/govuk_design_system_formbuilder/elements/text_area.rb +4 -8
- data/lib/govuk_design_system_formbuilder/version.rb +1 -1
- metadata +32 -12
- data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio.rb +0 -33
@@ -0,0 +1,28 @@
|
|
1
|
+
module GOVUKDesignSystemFormBuilder
|
2
|
+
module Containers
|
3
|
+
class CheckBoxesFieldset < GOVUKDesignSystemFormBuilder::Base
|
4
|
+
def initialize(builder, object_name, attribute_name, hint_text:, legend:, small:, &block)
|
5
|
+
super(builder, object_name, attribute_name)
|
6
|
+
|
7
|
+
@legend = legend
|
8
|
+
@hint_text = hint_text
|
9
|
+
@small = small
|
10
|
+
@block_content = @builder.capture { block.call }
|
11
|
+
end
|
12
|
+
|
13
|
+
def html
|
14
|
+
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
15
|
+
Containers::Fieldset.new(@builder, legend: @legend, described_by: [error_element.error_id, hint_element.hint_id]).html do
|
16
|
+
@builder.safe_join([
|
17
|
+
hint_element.html,
|
18
|
+
error_element.html,
|
19
|
+
Containers::CheckBoxes.new(@builder, small: @small).html do
|
20
|
+
@block_content
|
21
|
+
end
|
22
|
+
])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -7,7 +7,7 @@ module GOVUKDesignSystemFormBuilder
|
|
7
7
|
def initialize(builder, legend: {}, described_by: nil)
|
8
8
|
@builder = builder
|
9
9
|
@legend = LEGEND_DEFAULTS.merge(legend)
|
10
|
-
@described_by =
|
10
|
+
@described_by = described_by(described_by)
|
11
11
|
end
|
12
12
|
|
13
13
|
def html
|
@@ -35,20 +35,14 @@ module GOVUKDesignSystemFormBuilder
|
|
35
35
|
|
36
36
|
def legend_classes
|
37
37
|
size = @legend.dig(:size)
|
38
|
-
fail "invalid size #{size}, must be #{LEGEND_SIZES.join(', ')}" unless size.in?(LEGEND_SIZES)
|
38
|
+
fail "invalid size '#{size}', must be #{LEGEND_SIZES.join(', ')}" unless size.in?(LEGEND_SIZES)
|
39
39
|
|
40
|
-
"govuk-fieldset__legend govuk-fieldset__legend--#{size}"
|
40
|
+
["govuk-fieldset__legend", "govuk-fieldset__legend--#{size}"]
|
41
41
|
end
|
42
42
|
|
43
43
|
def legend_heading_classes
|
44
44
|
%(govuk-fieldset__heading)
|
45
45
|
end
|
46
|
-
|
47
|
-
def descriptors(described_by)
|
48
|
-
return nil unless described_by.present?
|
49
|
-
|
50
|
-
described_by.compact.join(' ').presence
|
51
|
-
end
|
52
46
|
end
|
53
47
|
end
|
54
48
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GOVUKDesignSystemFormBuilder
|
2
|
+
module Containers
|
3
|
+
class RadioButtonsFieldset < GOVUKDesignSystemFormBuilder::Base
|
4
|
+
def initialize(builder, object_name, attribute_name, hint_text:, legend:, inline:, small:, &block)
|
5
|
+
super(builder, object_name, attribute_name)
|
6
|
+
|
7
|
+
@inline = inline
|
8
|
+
@small = small
|
9
|
+
@legend = legend
|
10
|
+
@hint_text = hint_text
|
11
|
+
@block_content = @builder.capture { block.call }
|
12
|
+
end
|
13
|
+
|
14
|
+
def html
|
15
|
+
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
16
|
+
Containers::Fieldset.new(@builder, legend: @legend, described_by: [error_element.error_id, hint_element.hint_id]).html do
|
17
|
+
@builder.safe_join([
|
18
|
+
hint_element.html,
|
19
|
+
error_element.html,
|
20
|
+
Containers::Radios.new(@builder, inline: @inline, small: @small).html do
|
21
|
+
@block_content
|
22
|
+
end
|
23
|
+
])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module GOVUKDesignSystemFormBuilder
|
2
|
+
module Elements
|
3
|
+
module CheckBoxes
|
4
|
+
class Collection < GOVUKDesignSystemFormBuilder::Base
|
5
|
+
def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, hint_method: nil, hint_text:, legend:, small:, &block)
|
6
|
+
super(builder, object_name, attribute_name)
|
7
|
+
|
8
|
+
@collection = collection
|
9
|
+
@value_method = value_method
|
10
|
+
@text_method = text_method
|
11
|
+
@hint_method = hint_method
|
12
|
+
@small = small
|
13
|
+
@legend = legend
|
14
|
+
@hint_text = hint_text
|
15
|
+
@block_content = @builder.capture { block.call } if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def html
|
19
|
+
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
20
|
+
Containers::Fieldset.new(@builder, legend: @legend, described_by: [error_element.error_id, hint_element.hint_id]).html do
|
21
|
+
@builder.safe_join(
|
22
|
+
[
|
23
|
+
hint_element.html,
|
24
|
+
error_element.html,
|
25
|
+
@block_content,
|
26
|
+
Containers::CheckBoxes.new(@builder, small: @small).html do
|
27
|
+
build_collection
|
28
|
+
end
|
29
|
+
]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Builds a collection of check {Elements::CheckBoxes::CheckBox}
|
38
|
+
# @return [ActiveSupport::SafeBuffer] HTML output
|
39
|
+
#
|
40
|
+
# @note The GOV.UK design system requires that error summary links should
|
41
|
+
# link to the first checkbox directly. As we don't know if a collection will
|
42
|
+
# be rendered when it happens we need to work on the chance that it might, so
|
43
|
+
# the +link_errors+ variable is set to +true+ if this attribute has errors and
|
44
|
+
# always set back to +false+ after the first checkbox has been rendered
|
45
|
+
def build_collection
|
46
|
+
link_errors = has_errors?
|
47
|
+
|
48
|
+
@builder.collection_check_boxes(@attribute_name, @collection, @value_method, @text_method) do |check_box|
|
49
|
+
Elements::CheckBoxes::CollectionCheckBox.new(
|
50
|
+
@builder,
|
51
|
+
@object_name,
|
52
|
+
@attribute_name,
|
53
|
+
check_box,
|
54
|
+
@hint_method,
|
55
|
+
link_errors: link_errors
|
56
|
+
).html.tap { link_errors = false }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -2,26 +2,40 @@ module GOVUKDesignSystemFormBuilder
|
|
2
2
|
module Elements
|
3
3
|
module CheckBoxes
|
4
4
|
class CollectionCheckBox < GOVUKDesignSystemFormBuilder::Base
|
5
|
-
def initialize(builder,
|
6
|
-
|
7
|
-
@attribute = attribute
|
5
|
+
def initialize(builder, object_name, attribute_name, checkbox, hint_method = nil, link_errors: false)
|
6
|
+
super(builder, object_name, attribute_name)
|
8
7
|
@checkbox = checkbox
|
9
8
|
@item = checkbox.object
|
9
|
+
@value = checkbox.value
|
10
10
|
@hint_text = @item.send(hint_method) if hint_method.present?
|
11
|
+
@link_errors = link_errors
|
11
12
|
end
|
12
13
|
|
13
14
|
def html
|
14
|
-
hint = Hint.new(@builder, @attribute, @checkbox, @hint_text)
|
15
15
|
@builder.content_tag('div', class: 'govuk-checkboxes__item') do
|
16
16
|
@builder.safe_join(
|
17
17
|
[
|
18
|
-
@checkbox.check_box(
|
19
|
-
|
20
|
-
|
18
|
+
@checkbox.check_box(
|
19
|
+
id: field_id(link_errors: @link_errors),
|
20
|
+
class: "govuk-checkboxes__input",
|
21
|
+
aria: { describedby: hint_element.hint_id }
|
22
|
+
),
|
23
|
+
label_element.html,
|
24
|
+
hint_element.html
|
21
25
|
]
|
22
26
|
)
|
23
27
|
end
|
24
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def label_element
|
33
|
+
@label_element ||= Label.new(@checkbox, @object_name, @attribute_name, value: @value)
|
34
|
+
end
|
35
|
+
|
36
|
+
def hint_element
|
37
|
+
@hint_element ||= Hint.new(@builder, @object_name, @attribute_name, @hint_text, value: @value)
|
38
|
+
end
|
25
39
|
end
|
26
40
|
end
|
27
41
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module GOVUKDesignSystemFormBuilder
|
2
|
+
module Elements
|
3
|
+
module CheckBoxes
|
4
|
+
class FieldsetCheckBox < GOVUKDesignSystemFormBuilder::Base
|
5
|
+
def initialize(builder, object_name, attribute_name, value, label:, hint_text:, link_errors:, multiple:, &block)
|
6
|
+
super(builder, object_name, attribute_name)
|
7
|
+
|
8
|
+
@value = value
|
9
|
+
@label = label
|
10
|
+
@hint_text = hint_text
|
11
|
+
@multiple = multiple
|
12
|
+
@link_errors = link_errors
|
13
|
+
|
14
|
+
if block_given?
|
15
|
+
@conditional_content = wrap_conditional(block)
|
16
|
+
@conditional_id = conditional_id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def html
|
21
|
+
@builder.content_tag('div', class: 'govuk-checkboxes__item') do
|
22
|
+
@builder.safe_join([input, label, hint, @conditional_content])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def input
|
29
|
+
@builder.check_box(
|
30
|
+
@attribute_name,
|
31
|
+
{
|
32
|
+
id: field_id(link_errors: @link_errors),
|
33
|
+
class: check_box_classes,
|
34
|
+
multiple: @multiple,
|
35
|
+
aria: { describedby: hint_id },
|
36
|
+
data: { 'aria-controls' => @conditional_id }
|
37
|
+
},
|
38
|
+
@value,
|
39
|
+
false
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def label
|
44
|
+
Elements::Label.new(
|
45
|
+
@builder,
|
46
|
+
@object_name,
|
47
|
+
@attribute_name,
|
48
|
+
value: @value,
|
49
|
+
checkbox: true,
|
50
|
+
**@label,
|
51
|
+
).html
|
52
|
+
end
|
53
|
+
|
54
|
+
def hint
|
55
|
+
Elements::Hint.new(
|
56
|
+
@builder,
|
57
|
+
@object_name,
|
58
|
+
@attribute_name,
|
59
|
+
@hint_text,
|
60
|
+
@value,
|
61
|
+
checkbox: true
|
62
|
+
).html
|
63
|
+
end
|
64
|
+
|
65
|
+
def conditional_classes
|
66
|
+
%w(govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden)
|
67
|
+
end
|
68
|
+
|
69
|
+
def check_box_classes
|
70
|
+
%w(govuk-checkboxes__input)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,30 +1,22 @@
|
|
1
1
|
module GOVUKDesignSystemFormBuilder
|
2
2
|
module Elements
|
3
3
|
module CheckBoxes
|
4
|
-
class Hint
|
5
|
-
def initialize(builder,
|
6
|
-
|
7
|
-
|
8
|
-
@
|
9
|
-
@
|
4
|
+
class Hint < GOVUKDesignSystemFormBuilder::Base
|
5
|
+
def initialize(builder, object_name, attribute_name, hint_text, value:)
|
6
|
+
super(builder, object_name, attribute_name)
|
7
|
+
|
8
|
+
@value = value
|
9
|
+
@hint_text = hint_text
|
10
10
|
end
|
11
11
|
|
12
12
|
def html
|
13
|
-
return nil if @
|
13
|
+
return nil if @hint_text.blank?
|
14
14
|
|
15
|
-
@builder.tag.span(@
|
15
|
+
@builder.tag.span(@hint_text, class: hint_classes, id: id)
|
16
16
|
end
|
17
17
|
|
18
18
|
def id
|
19
|
-
|
20
|
-
|
21
|
-
[
|
22
|
-
@attribute,
|
23
|
-
@checkbox.object.id,
|
24
|
-
'hint'
|
25
|
-
]
|
26
|
-
.join('-')
|
27
|
-
.parameterize
|
19
|
+
hint_id
|
28
20
|
end
|
29
21
|
|
30
22
|
private
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module GOVUKDesignSystemFormBuilder
|
2
2
|
module Elements
|
3
3
|
module CheckBoxes
|
4
|
-
class Label
|
5
|
-
def initialize(builder)
|
6
|
-
|
4
|
+
class Label < GOVUKDesignSystemFormBuilder::Base
|
5
|
+
def initialize(builder, object_name, attribute_name, value:)
|
6
|
+
super(builder, object_name, attribute_name)
|
7
|
+
@value = value
|
7
8
|
end
|
8
9
|
|
9
10
|
def html
|
10
|
-
@builder.label(class: label_classes)
|
11
|
+
@builder.label(for: field_id, class: label_classes)
|
11
12
|
end
|
12
13
|
|
13
14
|
private
|
@@ -8,13 +8,10 @@ module GOVUKDesignSystemFormBuilder
|
|
8
8
|
@legend = legend
|
9
9
|
@hint_text = hint_text
|
10
10
|
@date_of_birth = date_of_birth
|
11
|
-
@block_content = @builder.capture { block.call }
|
11
|
+
@block_content = @builder.capture { block.call } if block_given?
|
12
12
|
end
|
13
13
|
|
14
14
|
def html
|
15
|
-
hint_element = Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text)
|
16
|
-
error_element = Elements::ErrorMessage.new(@builder, @object_name, @attribute_name)
|
17
|
-
|
18
15
|
Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
|
19
16
|
Containers::Fieldset.new(@builder, legend: @legend, described_by: [error_element.error_id, hint_element.hint_id]).html do
|
20
17
|
@builder.safe_join(
|
@@ -25,9 +22,9 @@ module GOVUKDesignSystemFormBuilder
|
|
25
22
|
@builder.content_tag('div', class: 'govuk-date-input') do
|
26
23
|
@builder.safe_join(
|
27
24
|
[
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
date_input_item(:day, link_errors: true),
|
26
|
+
date_input_item(:month),
|
27
|
+
date_input_item(:year, width: 4)
|
31
28
|
]
|
32
29
|
)
|
33
30
|
end
|
@@ -39,7 +36,7 @@ module GOVUKDesignSystemFormBuilder
|
|
39
36
|
|
40
37
|
private
|
41
38
|
|
42
|
-
def
|
39
|
+
def date_input_item(segment, width: 2, link_errors: false)
|
43
40
|
value = @builder.object.try(@attribute_name).try(segment)
|
44
41
|
|
45
42
|
@builder.content_tag('div', class: %w(govuk-date-input__item)) do
|
@@ -49,13 +46,13 @@ module GOVUKDesignSystemFormBuilder
|
|
49
46
|
@builder.tag.label(
|
50
47
|
segment.capitalize,
|
51
48
|
class: date_input_label_classes,
|
52
|
-
for:
|
49
|
+
for: date_attribute_id(segment, link_errors)
|
53
50
|
),
|
54
51
|
|
55
52
|
@builder.tag.input(
|
56
|
-
id:
|
53
|
+
id: date_attribute_id(segment, link_errors),
|
57
54
|
class: date_input_classes(width),
|
58
|
-
name:
|
55
|
+
name: date_attribute_name(segment),
|
59
56
|
type: 'text',
|
60
57
|
pattern: '[0-9]*',
|
61
58
|
inputmode: 'numeric',
|
@@ -79,11 +76,18 @@ module GOVUKDesignSystemFormBuilder
|
|
79
76
|
%w(govuk-label govuk-date-input__label)
|
80
77
|
end
|
81
78
|
|
82
|
-
|
83
|
-
|
79
|
+
# if the field has errors we want the govuk_error_summary to
|
80
|
+
# be able to link to the day field. Otherwise, generate IDs
|
81
|
+
# in the normal fashion
|
82
|
+
def date_attribute_id(segment, link_errors)
|
83
|
+
if has_errors? && link_errors
|
84
|
+
field_id(link_errors: link_errors)
|
85
|
+
else
|
86
|
+
[@object_name, @attribute_name, SEGMENTS.fetch(segment)].join("_")
|
87
|
+
end
|
84
88
|
end
|
85
89
|
|
86
|
-
def
|
90
|
+
def date_attribute_name(segment)
|
87
91
|
"%<object_name>s[%<attribute_name>s(%<segment>s)]" % {
|
88
92
|
object_name: @object_name,
|
89
93
|
attribute_name: @attribute_name,
|
@@ -9,10 +9,12 @@ module GOVUKDesignSystemFormBuilder
|
|
9
9
|
return nil unless has_errors?
|
10
10
|
|
11
11
|
@builder.content_tag('span', class: 'govuk-error-message', id: error_id) do
|
12
|
-
@builder.safe_join(
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
@builder.safe_join(
|
13
|
+
[
|
14
|
+
@builder.tag.span('Error: ', class: 'govuk-visually-hidden'),
|
15
|
+
message
|
16
|
+
]
|
17
|
+
)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
@@ -10,12 +10,12 @@ module GOVUKDesignSystemFormBuilder
|
|
10
10
|
def html
|
11
11
|
return nil unless object_has_errors?
|
12
12
|
|
13
|
-
@builder.content_tag('div', class:
|
13
|
+
@builder.content_tag('div', class: summary_class, **error_summary_attributes) do
|
14
14
|
@builder.safe_join(
|
15
15
|
[
|
16
|
-
@builder.tag.h2(@title, id: error_summary_title_id, class: '
|
17
|
-
@builder.content_tag('div', class: '
|
18
|
-
@builder.content_tag('ul', class: 'govuk-list
|
16
|
+
@builder.tag.h2(@title, id: error_summary_title_id, class: summary_class('title')),
|
17
|
+
@builder.content_tag('div', class: summary_class('body')) do
|
18
|
+
@builder.content_tag('ul', class: ['govuk-list', summary_class('list')]) do
|
19
19
|
@builder.safe_join(
|
20
20
|
@builder.object.errors.messages.map do |attribute, messages|
|
21
21
|
error_list_item(attribute, messages)
|
@@ -32,15 +32,30 @@ module GOVUKDesignSystemFormBuilder
|
|
32
32
|
|
33
33
|
def error_list_item(attribute, messages)
|
34
34
|
@builder.content_tag('li') do
|
35
|
-
@builder.
|
35
|
+
@builder.link_to(
|
36
36
|
messages.join(', '),
|
37
|
-
|
37
|
+
same_page_link(field_id(attribute)),
|
38
|
+
data: {
|
39
|
+
turbolinks: false
|
40
|
+
}
|
38
41
|
)
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
42
|
-
def
|
43
|
-
|
45
|
+
def same_page_link(target)
|
46
|
+
'#'.concat(target)
|
47
|
+
end
|
48
|
+
|
49
|
+
def summary_class(part = nil)
|
50
|
+
if part
|
51
|
+
'govuk-error-summary'.concat('__', part)
|
52
|
+
else
|
53
|
+
'govuk-error-summary'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def field_id(attribute)
|
58
|
+
build_id('field-error', attribute_name: attribute)
|
44
59
|
end
|
45
60
|
|
46
61
|
def error_summary_title_id
|