govuk_design_system_formbuilder 2.1.9 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -0
  3. data/README.md +2 -2
  4. data/lib/govuk_design_system_formbuilder.rb +8 -1
  5. data/lib/govuk_design_system_formbuilder/base.rb +16 -1
  6. data/lib/govuk_design_system_formbuilder/builder.rb +60 -15
  7. data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +2 -2
  8. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +12 -9
  9. data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +2 -2
  10. data/lib/govuk_design_system_formbuilder/containers/supplemental.rb +1 -1
  11. data/lib/govuk_design_system_formbuilder/elements/caption.rb +3 -3
  12. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +2 -2
  13. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +2 -2
  14. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +5 -3
  15. data/lib/govuk_design_system_formbuilder/elements/collection_select.rb +52 -0
  16. data/lib/govuk_design_system_formbuilder/elements/date.rb +33 -15
  17. data/lib/govuk_design_system_formbuilder/elements/error_message.rb +1 -1
  18. data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +11 -4
  19. data/lib/govuk_design_system_formbuilder/elements/file.rb +3 -2
  20. data/lib/govuk_design_system_formbuilder/elements/hint.rb +1 -1
  21. data/lib/govuk_design_system_formbuilder/elements/inputs/email.rb +1 -0
  22. data/lib/govuk_design_system_formbuilder/elements/inputs/number.rb +1 -0
  23. data/lib/govuk_design_system_formbuilder/elements/inputs/password.rb +1 -0
  24. data/lib/govuk_design_system_formbuilder/elements/inputs/phone.rb +1 -0
  25. data/lib/govuk_design_system_formbuilder/elements/inputs/text.rb +1 -0
  26. data/lib/govuk_design_system_formbuilder/elements/inputs/url.rb +1 -0
  27. data/lib/govuk_design_system_formbuilder/elements/label.rb +3 -3
  28. data/lib/govuk_design_system_formbuilder/elements/legend.rb +3 -5
  29. data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +3 -3
  30. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +3 -3
  31. data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +9 -7
  32. data/lib/govuk_design_system_formbuilder/elements/select.rb +22 -32
  33. data/lib/govuk_design_system_formbuilder/elements/submit.rb +17 -14
  34. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +5 -4
  35. data/lib/govuk_design_system_formbuilder/traits/caption.rb +1 -1
  36. data/lib/govuk_design_system_formbuilder/traits/error.rb +2 -2
  37. data/lib/govuk_design_system_formbuilder/traits/fieldset_item.rb +2 -2
  38. data/lib/govuk_design_system_formbuilder/traits/hint.rb +2 -2
  39. data/lib/govuk_design_system_formbuilder/traits/html_attributes.rb +51 -0
  40. data/lib/govuk_design_system_formbuilder/traits/input.rb +5 -5
  41. data/lib/govuk_design_system_formbuilder/traits/label.rb +1 -1
  42. data/lib/govuk_design_system_formbuilder/traits/select.rb +15 -0
  43. data/lib/govuk_design_system_formbuilder/traits/supplemental.rb +2 -2
  44. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  45. metadata +45 -13
@@ -8,8 +8,9 @@ module GOVUKDesignSystemFormBuilder
8
8
  include Traits::Hint
9
9
  include Traits::FieldsetItem
10
10
  include Traits::Conditional
11
+ include Traits::HTMLAttributes
11
12
 
12
- def initialize(builder, object_name, attribute_name, value, unchecked_value, label:, hint:, link_errors:, multiple:, &block)
13
+ def initialize(builder, object_name, attribute_name, value, unchecked_value, label:, hint:, link_errors:, multiple:, **kwargs, &block)
13
14
  super(builder, object_name, attribute_name)
14
15
 
15
16
  @value = value
@@ -18,6 +19,7 @@ module GOVUKDesignSystemFormBuilder
18
19
  @hint = hint
19
20
  @multiple = multiple
20
21
  @link_errors = link_errors
22
+ @html_attributes = kwargs
21
23
 
22
24
  if block_given?
23
25
  @conditional_content = wrap_conditional(block)
@@ -38,7 +40,7 @@ module GOVUKDesignSystemFormBuilder
38
40
  end
39
41
 
40
42
  def check_box
41
- @builder.check_box(@attribute_name, options, @value, @unchecked_value)
43
+ @builder.check_box(@attribute_name, attributes(@html_attributes), @value, @unchecked_value)
42
44
  end
43
45
 
44
46
  def options
@@ -46,7 +48,7 @@ module GOVUKDesignSystemFormBuilder
46
48
  id: field_id(link_errors: @link_errors),
47
49
  class: classes,
48
50
  multiple: @multiple,
49
- aria: { describedby: hint_id },
51
+ aria: { describedby: [hint_id] },
50
52
  data: { 'aria-controls' => @conditional_id }
51
53
  }
52
54
  end
@@ -0,0 +1,52 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ class CollectionSelect < Base
4
+ include Traits::Error
5
+ include Traits::Label
6
+ include Traits::Hint
7
+ include Traits::Supplemental
8
+ include Traits::HTMLAttributes
9
+ include Traits::Select
10
+
11
+ def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, hint:, label:, caption:, form_group:, options: {}, **kwargs, &block)
12
+ super(builder, object_name, attribute_name, &block)
13
+
14
+ @collection = collection
15
+ @value_method = value_method
16
+ @text_method = text_method
17
+ @options = options
18
+ @label = label
19
+ @caption = caption
20
+ @hint = hint
21
+ @form_group = form_group
22
+ @html_attributes = kwargs
23
+
24
+ # FIXME remove this soon, worth informing people who miss the release notes that the
25
+ # args have changed though.
26
+ if :html_options.in?(kwargs.keys)
27
+ warn("GOVUKDesignSystemFormBuilder: html_options has been deprecated, use keyword arguments instead")
28
+ end
29
+ end
30
+
31
+ def html
32
+ Containers::FormGroup.new(*bound, **@form_group).html do
33
+ safe_join([label_element, supplemental_content, hint_element, error_element, collection_select])
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def options
40
+ {
41
+ id: field_id(link_errors: true),
42
+ class: classes,
43
+ aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
44
+ }
45
+ end
46
+
47
+ def collection_select
48
+ @builder.collection_select(@attribute_name, @collection, @value_method, @text_method, @options, **attributes(@html_attributes))
49
+ end
50
+ end
51
+ end
52
+ end
@@ -8,22 +8,24 @@ module GOVUKDesignSystemFormBuilder
8
8
  include Traits::Supplemental
9
9
 
10
10
  SEGMENTS = { day: '3i', month: '2i', year: '1i' }.freeze
11
+ MULTIPARAMETER_KEY = { day: 3, month: 2, year: 1 }.freeze
11
12
 
12
- def initialize(builder, object_name, attribute_name, legend:, caption:, hint:, omit_day:, form_group:, wildcards:, date_of_birth: false, &block)
13
+ def initialize(builder, object_name, attribute_name, legend:, caption:, hint:, omit_day:, form_group:, wildcards:, date_of_birth: false, **kwargs, &block)
13
14
  super(builder, object_name, attribute_name, &block)
14
15
 
15
- @legend = legend
16
- @caption = caption
17
- @hint = hint
18
- @date_of_birth = date_of_birth
19
- @omit_day = omit_day
20
- @form_group = form_group
21
- @wildcards = wildcards
16
+ @legend = legend
17
+ @caption = caption
18
+ @hint = hint
19
+ @date_of_birth = date_of_birth
20
+ @omit_day = omit_day
21
+ @form_group = form_group
22
+ @wildcards = wildcards
23
+ @html_attributes = kwargs
22
24
  end
23
25
 
24
26
  def html
25
- Containers::FormGroup.new(@builder, @object_name, @attribute_name, **@form_group).html do
26
- Containers::Fieldset.new(@builder, @object_name, @attribute_name, **fieldset_options).html do
27
+ Containers::FormGroup.new(*bound, **@form_group, **@html_attributes).html do
28
+ Containers::Fieldset.new(*bound, **fieldset_options).html do
27
29
  safe_join([supplemental_content, hint_element, error_element, date])
28
30
  end
29
31
  end
@@ -46,7 +48,7 @@ module GOVUKDesignSystemFormBuilder
46
48
  end
47
49
 
48
50
  def day
49
- return nil if omit_day?
51
+ return if omit_day?
50
52
 
51
53
  date_part(:day, width: 2, link_errors: true)
52
54
  end
@@ -60,15 +62,31 @@ module GOVUKDesignSystemFormBuilder
60
62
  end
61
63
 
62
64
  def date_part(segment, width:, link_errors: false)
63
- value = @builder.object.try(@attribute_name).try(segment)
64
-
65
65
  tag.div(class: %(#{brand}-date-input__item)) do
66
66
  tag.div(class: %(#{brand}-form-group)) do
67
- safe_join([label(segment, link_errors), input(segment, link_errors, width, value)])
67
+ safe_join([label(segment, link_errors), input(segment, link_errors, width, value(segment))])
68
68
  end
69
69
  end
70
70
  end
71
71
 
72
+ def value(segment)
73
+ attribute = @builder.object.try(@attribute_name)
74
+
75
+ return unless attribute
76
+
77
+ if attribute.respond_to?(segment)
78
+ attribute.send(segment)
79
+ elsif attribute.respond_to?(:fetch)
80
+ attribute.fetch(MULTIPARAMETER_KEY[segment]) do
81
+ warn("No key '#{segment}' found in MULTIPARAMETER_KEY hash. Expected to find #{MULTIPARAMETER_KEY.values}")
82
+
83
+ nil
84
+ end
85
+ else
86
+ fail(ArgumentError, "invalid Date-like object: must be a Date, Time, DateTime or Hash in MULTIPARAMETER_KEY format")
87
+ end
88
+ end
89
+
72
90
  def label(segment, link_errors)
73
91
  tag.label(
74
92
  segment.capitalize,
@@ -124,7 +142,7 @@ module GOVUKDesignSystemFormBuilder
124
142
  end
125
143
 
126
144
  def date_of_birth_autocomplete_value(segment)
127
- return nil unless @date_of_birth
145
+ return unless @date_of_birth
128
146
 
129
147
  { day: 'bday-day', month: 'bday-month', year: 'bday-year' }.fetch(segment)
130
148
  end
@@ -6,7 +6,7 @@ module GOVUKDesignSystemFormBuilder
6
6
  include Traits::Error
7
7
 
8
8
  def html
9
- return nil unless has_errors?
9
+ return unless has_errors?
10
10
 
11
11
  tag.span(class: %(#{brand}-error-message), id: error_id) do
12
12
  safe_join([hidden_prefix, message])
@@ -2,18 +2,20 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  class ErrorSummary < Base
4
4
  include Traits::Error
5
+ include Traits::HTMLAttributes
5
6
 
6
- def initialize(builder, object_name, title, link_base_errors_to:)
7
+ def initialize(builder, object_name, title, link_base_errors_to:, **kwargs)
7
8
  super(builder, object_name, nil)
8
9
 
9
10
  @title = title
10
11
  @link_base_errors_to = link_base_errors_to
12
+ @html_attributes = kwargs
11
13
  end
12
14
 
13
15
  def html
14
- return nil unless object_has_errors?
16
+ return unless object_has_errors?
15
17
 
16
- tag.div(class: summary_class, **summary_options) do
18
+ tag.div(**attributes(@html_attributes)) do
17
19
  safe_join([title, summary])
18
20
  end
19
21
  end
@@ -46,6 +48,10 @@ module GOVUKDesignSystemFormBuilder
46
48
  '#'.concat(target)
47
49
  end
48
50
 
51
+ def classes
52
+ Array.wrap(summary_class)
53
+ end
54
+
49
55
  def summary_class(part = nil)
50
56
  if part
51
57
  %(#{brand}-error-summary).concat('__', part)
@@ -70,8 +76,9 @@ module GOVUKDesignSystemFormBuilder
70
76
  @builder.object.errors.any?
71
77
  end
72
78
 
73
- def summary_options
79
+ def options
74
80
  {
81
+ class: classes,
75
82
  tabindex: -1,
76
83
  role: 'alert',
77
84
  data: {
@@ -7,6 +7,7 @@ module GOVUKDesignSystemFormBuilder
7
7
  include Traits::Hint
8
8
  include Traits::Label
9
9
  include Traits::Supplemental
10
+ include Traits::HTMLAttributes
10
11
 
11
12
  def initialize(builder, object_name, attribute_name, hint:, label:, caption:, form_group:, **kwargs, &block)
12
13
  super(builder, object_name, attribute_name, &block)
@@ -19,7 +20,7 @@ module GOVUKDesignSystemFormBuilder
19
20
  end
20
21
 
21
22
  def html
22
- Containers::FormGroup.new(@builder, @object_name, @attribute_name, **@form_group).html do
23
+ Containers::FormGroup.new(*bound, **@form_group).html do
23
24
  safe_join([label_element, supplemental_content, hint_element, error_element, file])
24
25
  end
25
26
  end
@@ -27,7 +28,7 @@ module GOVUKDesignSystemFormBuilder
27
28
  private
28
29
 
29
30
  def file
30
- @builder.file_field(@attribute_name, **options, **@html_attributes)
31
+ @builder.file_field(@attribute_name, attributes(@html_attributes))
31
32
  end
32
33
 
33
34
  def options
@@ -31,7 +31,7 @@ module GOVUKDesignSystemFormBuilder
31
31
  end
32
32
 
33
33
  def hint_id
34
- return nil unless active?
34
+ return unless active?
35
35
 
36
36
  build_id('hint')
37
37
  end
@@ -7,6 +7,7 @@ module GOVUKDesignSystemFormBuilder
7
7
  include Traits::Hint
8
8
  include Traits::Label
9
9
  include Traits::Supplemental
10
+ include Traits::HTMLAttributes
10
11
 
11
12
  private
12
13
 
@@ -7,6 +7,7 @@ module GOVUKDesignSystemFormBuilder
7
7
  include Traits::Hint
8
8
  include Traits::Label
9
9
  include Traits::Supplemental
10
+ include Traits::HTMLAttributes
10
11
 
11
12
  def builder_method
12
13
  :number_field
@@ -7,6 +7,7 @@ module GOVUKDesignSystemFormBuilder
7
7
  include Traits::Hint
8
8
  include Traits::Label
9
9
  include Traits::Supplemental
10
+ include Traits::HTMLAttributes
10
11
 
11
12
  def builder_method
12
13
  :password_field
@@ -7,6 +7,7 @@ module GOVUKDesignSystemFormBuilder
7
7
  include Traits::Hint
8
8
  include Traits::Label
9
9
  include Traits::Supplemental
10
+ include Traits::HTMLAttributes
10
11
 
11
12
  def builder_method
12
13
  :phone_field
@@ -7,6 +7,7 @@ module GOVUKDesignSystemFormBuilder
7
7
  include Traits::Hint
8
8
  include Traits::Label
9
9
  include Traits::Supplemental
10
+ include Traits::HTMLAttributes
10
11
 
11
12
  def builder_method
12
13
  :text_field
@@ -7,6 +7,7 @@ module GOVUKDesignSystemFormBuilder
7
7
  include Traits::Hint
8
8
  include Traits::Label
9
9
  include Traits::Supplemental
10
+ include Traits::HTMLAttributes
10
11
 
11
12
  def builder_method
12
13
  :url_field
@@ -28,7 +28,7 @@ module GOVUKDesignSystemFormBuilder
28
28
  end
29
29
 
30
30
  def html
31
- return nil unless active?
31
+ return unless active?
32
32
 
33
33
  if @tag.present?
34
34
  content_tag(@tag, class: %(#{brand}-label-wrapper)) { label }
@@ -72,13 +72,13 @@ module GOVUKDesignSystemFormBuilder
72
72
  end
73
73
 
74
74
  def radio_class
75
- return nil unless @radio
75
+ return unless @radio
76
76
 
77
77
  %(#{brand}-radios__label)
78
78
  end
79
79
 
80
80
  def checkbox_class
81
- return nil unless @checkbox
81
+ return unless @checkbox
82
82
 
83
83
  %(#{brand}-checkboxes__label)
84
84
  end
@@ -39,11 +39,9 @@ module GOVUKDesignSystemFormBuilder
39
39
  def legend_content
40
40
  caption_and_text = safe_join([caption_element, @text])
41
41
 
42
- if @tag.present?
43
- content_tag(@tag, class: heading_classes) { caption_and_text }
44
- else
45
- caption_and_text
46
- end
42
+ return caption_and_text if @tag.blank?
43
+
44
+ content_tag(@tag, class: heading_classes) { caption_and_text }
47
45
  end
48
46
 
49
47
  def retrieve_text(supplied_text)
@@ -25,8 +25,8 @@ module GOVUKDesignSystemFormBuilder
25
25
  end
26
26
 
27
27
  def html
28
- Containers::FormGroup.new(@builder, @object_name, @attribute_name, **@form_group).html do
29
- Containers::Fieldset.new(@builder, @object_name, @attribute_name, **fieldset_options).html do
28
+ Containers::FormGroup.new(*bound, **@form_group).html do
29
+ Containers::Fieldset.new(*bound, **fieldset_options).html do
30
30
  safe_join([hidden_field, supplemental_content, hint_element, error_element, radios])
31
31
  end
32
32
  end
@@ -56,7 +56,7 @@ module GOVUKDesignSystemFormBuilder
56
56
 
57
57
  def collection
58
58
  @collection.map.with_index do |item, i|
59
- Elements::Radios::CollectionRadioButton.new(@builder, @object_name, @attribute_name, item, **collection_options(i)).html
59
+ Elements::Radios::CollectionRadioButton.new(*bound, item, **collection_options(i)).html
60
60
  end
61
61
  end
62
62
 
@@ -9,7 +9,7 @@ module GOVUKDesignSystemFormBuilder
9
9
  # error summary requires that the id of the first radio is linked-to from the corresponding
10
10
  # error message. As when the summary is built what happens later in the form is unknown, we
11
11
  # need to control this to ensure the link is generated correctly
12
- def initialize(builder, object_name, attribute_name, item, value_method:, text_method:, hint_method:, link_errors: false, bold_labels:)
12
+ def initialize(builder, object_name, attribute_name, item, value_method:, text_method:, hint_method:, bold_labels:, link_errors: false)
13
13
  super(builder, object_name, attribute_name)
14
14
 
15
15
  @item = item
@@ -41,7 +41,7 @@ module GOVUKDesignSystemFormBuilder
41
41
  end
42
42
 
43
43
  def hint_element
44
- @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, **hint_options, **hint_content)
44
+ @hint_element ||= Elements::Hint.new(*bound, **hint_options, **hint_content)
45
45
  end
46
46
 
47
47
  def hint_content
@@ -53,7 +53,7 @@ module GOVUKDesignSystemFormBuilder
53
53
  end
54
54
 
55
55
  def label_element
56
- @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, **label_options)
56
+ @label_element ||= Elements::Label.new(*bound, **label_options)
57
57
  end
58
58
 
59
59
  def label_options
@@ -8,14 +8,16 @@ module GOVUKDesignSystemFormBuilder
8
8
  include Traits::Hint
9
9
  include Traits::FieldsetItem
10
10
  include Traits::Conditional
11
+ include Traits::HTMLAttributes
11
12
 
12
- def initialize(builder, object_name, attribute_name, value, label:, hint:, link_errors:, &block)
13
+ def initialize(builder, object_name, attribute_name, value, label:, hint:, link_errors:, **kwargs, &block)
13
14
  super(builder, object_name, attribute_name)
14
15
 
15
- @value = value
16
- @label = label
17
- @hint = hint
18
- @link_errors = has_errors? && link_errors
16
+ @value = value
17
+ @label = label
18
+ @hint = hint
19
+ @link_errors = has_errors? && link_errors
20
+ @html_attributes = kwargs
19
21
 
20
22
  if block_given?
21
23
  @conditional_content = wrap_conditional(block)
@@ -40,13 +42,13 @@ module GOVUKDesignSystemFormBuilder
40
42
  end
41
43
 
42
44
  def input
43
- @builder.radio_button(@attribute_name, @value, **options)
45
+ @builder.radio_button(@attribute_name, @value, **attributes(@html_attributes))
44
46
  end
45
47
 
46
48
  def options
47
49
  {
48
50
  id: field_id(link_errors: @link_errors),
49
- aria: { describedby: hint_id },
51
+ aria: { describedby: [hint_id] },
50
52
  data: { 'aria-controls' => @conditional_id },
51
53
  class: %w(radios__input).prefix(brand)
52
54
  }