govuk_design_system_formbuilder 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/lib/govuk_design_system_formbuilder/base.rb +5 -0
  3. data/lib/govuk_design_system_formbuilder/builder.rb +3 -4
  4. data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +9 -9
  5. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +3 -3
  6. data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +9 -9
  7. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +8 -11
  8. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +17 -15
  9. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +19 -27
  10. data/lib/govuk_design_system_formbuilder/elements/date.rb +20 -23
  11. data/lib/govuk_design_system_formbuilder/elements/error_message.rb +8 -7
  12. data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +23 -26
  13. data/lib/govuk_design_system_formbuilder/elements/file.rb +18 -20
  14. data/lib/govuk_design_system_formbuilder/elements/hint.rb +1 -4
  15. data/lib/govuk_design_system_formbuilder/elements/label.rb +12 -9
  16. data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +23 -22
  17. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +13 -13
  18. data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +14 -19
  19. data/lib/govuk_design_system_formbuilder/elements/select.rb +6 -17
  20. data/lib/govuk_design_system_formbuilder/elements/submit.rb +24 -23
  21. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +16 -23
  22. data/lib/govuk_design_system_formbuilder/traits/caption.rb +5 -6
  23. data/lib/govuk_design_system_formbuilder/traits/input.rb +19 -28
  24. data/lib/govuk_design_system_formbuilder/traits/label.rb +2 -2
  25. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  26. metadata +9 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db9e3152ce56de44fbcb67ed0110cf9613ed0180597baf36cbc93316c41c72c5
4
- data.tar.gz: 5df5f7b19116b6846cbe305e14006993b86194db2677017c29344f7132ad6f54
3
+ metadata.gz: 03bf04be59daef7eecb295ca78d3a26399c474840e93ddc7866db8a79a00985f
4
+ data.tar.gz: 0bea59a672cdeedd539ac1e9a1a00435a434ddc2f7324b4e8df75db8ccc36595
5
5
  SHA512:
6
- metadata.gz: bfc94cbbf30b95c91c136dd00db6d666d631d94edcecb0e673eb9e03d0771b739b00a58708c967cf720a4dc1bc10af929faea8aee8b6f44ab2916434a0c0bc7f
7
- data.tar.gz: 721f67fb7fa2eb2883fd6d47c89b4aa86b4dcdae371501fb151d9d050132be1a59a739197216c1726566fb1f28bbba9a64fbc41dd8eec4b946abaddddb06bc3f
6
+ metadata.gz: 22028ec7e2f2b6d6ea5497a24dbfd88e7bf99fd22c5794f35d369814efd1728bd43c3a95adbc1e9805b4b1c54acf31c66db460d70dcb1504535de171e044bdb2
7
+ data.tar.gz: 640a062cc8f40cc68acc6779284357d24b3963d4f7b417b5a2383fdca85fa5fc064b382e2250098e950202485ab87a0603b766ce4b5d728412b4df04baa9e937
@@ -18,6 +18,11 @@ module GOVUKDesignSystemFormBuilder
18
18
  @block_content = capture { block.call } if block_given?
19
19
  end
20
20
 
21
+ # objects that implement #to_s can be passed directly into #safe_join
22
+ def to_s
23
+ html || ''
24
+ end
25
+
21
26
  private
22
27
 
23
28
  def brand(override = nil)
@@ -677,14 +677,13 @@ module GOVUKDesignSystemFormBuilder
677
677
  # @param text [String] the button text
678
678
  # @param warning [Boolean] makes the button red ({https://design-system.service.gov.uk/components/button/#warning-buttons warning}) when true
679
679
  # @param secondary [Boolean] makes the button grey ({https://design-system.service.gov.uk/components/button/#secondary-buttons secondary}) when true
680
- # @todo The GOV.UK design system also supports {https://design-system.service.gov.uk/components/button/#disabled-buttons disabled buttons}, they
681
- # should probably be supported too
682
680
  # @param classes [String] Classes to add to the submit button
683
681
  # @param prevent_double_click [Boolean] adds JavaScript to safeguard the
684
682
  # form from being submitted more than once
685
683
  # @param validate [Boolean] adds the formnovalidate to the submit button when true, this disables all
686
684
  # client-side validation provided by the browser. This is to provide a more consistent and accessible user
687
685
  # experience
686
+ # @param disabled [Boolean] makes the button disabled when true
688
687
  # @param block [Block] Any supplied HTML will be inserted immediately after
689
688
  # the submit button. It is intended for other buttons directly related to
690
689
  # the form's operation, such as 'Cancel' or 'Safe draft'
@@ -699,8 +698,8 @@ module GOVUKDesignSystemFormBuilder
699
698
  # = f.govuk_submit "Proceed", prevent_double_click: true do
700
699
  # = link_to 'Cancel', some_other_path, class: 'govuk-button__secondary'
701
700
  #
702
- def govuk_submit(text = config.default_submit_button_text, warning: false, secondary: false, classes: nil, prevent_double_click: true, validate: false, &block)
703
- Elements::Submit.new(self, text, warning: warning, secondary: secondary, classes: classes, prevent_double_click: prevent_double_click, validate: validate, &block).html
701
+ def govuk_submit(text = config.default_submit_button_text, warning: false, secondary: false, classes: nil, prevent_double_click: true, validate: false, disabled: false, &block)
702
+ Elements::Submit.new(self, text, warning: warning, secondary: secondary, classes: classes, prevent_double_click: prevent_double_click, validate: validate, disabled: disabled, &block).html
704
703
  end
705
704
 
706
705
  # Generates three inputs for the +day+, +month+ and +year+ components of a date
@@ -18,18 +18,18 @@ module GOVUKDesignSystemFormBuilder
18
18
  def html
19
19
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
20
20
  Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_element.error_id, hint_element.hint_id]).html do
21
- safe_join(
22
- [
23
- hint_element.html,
24
- error_element.html,
25
- Containers::CheckBoxes.new(@builder, small: @small, classes: @classes).html do
26
- @block_content
27
- end
28
- ]
29
- )
21
+ safe_join([hint_element, error_element, checkboxes])
30
22
  end
31
23
  end
32
24
  end
25
+
26
+ private
27
+
28
+ def checkboxes
29
+ Containers::CheckBoxes.new(@builder, small: @small, classes: @classes).html do
30
+ @block_content
31
+ end
32
+ end
33
33
  end
34
34
  end
35
35
  end
@@ -34,14 +34,14 @@ module GOVUKDesignSystemFormBuilder
34
34
  private
35
35
 
36
36
  def legend_content
37
- @legend_raw || build_legend
37
+ @legend_raw || legend
38
38
  end
39
39
 
40
- def build_legend
40
+ def legend
41
41
  if legend_text.present?
42
42
  content_tag('legend', class: legend_classes) do
43
43
  content_tag(@legend_options.dig(:tag), class: legend_heading_classes) do
44
- safe_join([caption_element.html, legend_text])
44
+ safe_join([caption_element, legend_text])
45
45
  end
46
46
  end
47
47
  end
@@ -19,18 +19,18 @@ module GOVUKDesignSystemFormBuilder
19
19
  def html
20
20
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
21
21
  Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_element.error_id, hint_element.hint_id]).html do
22
- safe_join(
23
- [
24
- hint_element.html,
25
- error_element.html,
26
- Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
27
- @block_content
28
- end
29
- ]
30
- )
22
+ safe_join([hint_element, error_element, radios])
31
23
  end
32
24
  end
33
25
  end
26
+
27
+ private
28
+
29
+ def radios
30
+ Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
31
+ @block_content
32
+ end
33
+ end
34
34
  end
35
35
  end
36
36
  end
@@ -23,22 +23,19 @@ module GOVUKDesignSystemFormBuilder
23
23
  def html
24
24
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
25
25
  Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id]).html do
26
- safe_join(
27
- [
28
- supplemental_content.html,
29
- hint_element.html,
30
- error_element.html,
31
- Containers::CheckBoxes.new(@builder, small: @small, classes: @classes).html do
32
- build_collection
33
- end
34
- ]
35
- )
26
+ safe_join([supplemental_content, hint_element, error_element, check_boxes])
36
27
  end
37
28
  end
38
29
  end
39
30
 
40
31
  private
41
32
 
33
+ def check_boxes
34
+ Containers::CheckBoxes.new(@builder, small: @small, classes: @classes).html do
35
+ collection
36
+ end
37
+ end
38
+
42
39
  # Builds a collection of check {Elements::CheckBoxes::CheckBox}
43
40
  # @return [ActiveSupport::SafeBuffer] HTML output
44
41
  #
@@ -47,7 +44,7 @@ module GOVUKDesignSystemFormBuilder
47
44
  # be rendered when it happens we need to work on the chance that it might, so
48
45
  # the +link_errors+ variable is set to +true+ if this attribute has errors and
49
46
  # always set back to +false+ after the first checkbox has been rendered
50
- def build_collection
47
+ def collection
51
48
  link_errors = has_errors?
52
49
 
53
50
  @builder.collection_check_boxes(@attribute_name, @collection, @value_method, @text_method) do |check_box|
@@ -10,31 +10,33 @@ module GOVUKDesignSystemFormBuilder
10
10
  def initialize(builder, object_name, attribute_name, checkbox, hint_method = nil, link_errors: false)
11
11
  super(builder, object_name, attribute_name)
12
12
 
13
- @checkbox = checkbox
14
- @item = checkbox.object
15
- @value = checkbox.value
16
- @hint_text = retrieve(@item, hint_method)
13
+ @checkbox = checkbox
14
+ @item = checkbox.object
15
+ @value = checkbox.value
16
+ @hint_text = retrieve(@item, hint_method)
17
17
  @link_errors = link_errors
18
18
  end
19
19
 
20
20
  def html
21
21
  content_tag('div', class: %(#{brand}-checkboxes__item)) do
22
- safe_join(
23
- [
24
- @checkbox.check_box(
25
- id: field_id(link_errors: @link_errors),
26
- class: %(#{brand}-checkboxes__input),
27
- aria: { describedby: hint_id }
28
- ),
29
- label_element.html,
30
- hint_element.html
31
- ]
32
- )
22
+ safe_join([check_box, label_element, hint_element])
33
23
  end
34
24
  end
35
25
 
36
26
  private
37
27
 
28
+ def check_box
29
+ @checkbox.check_box(**check_box_options)
30
+ end
31
+
32
+ def check_box_options
33
+ {
34
+ id: field_id(link_errors: @link_errors),
35
+ class: %(#{brand}-checkboxes__input),
36
+ aria: { describedby: hint_id }
37
+ }
38
+ end
39
+
38
40
  def label_element
39
41
  @label_element ||= Label.new(@builder, @object_name, @attribute_name, @checkbox, value: @value, link_errors: @link_errors)
40
42
  end
@@ -24,41 +24,33 @@ module GOVUKDesignSystemFormBuilder
24
24
  end
25
25
 
26
26
  def html
27
- safe_join(
28
- [
29
- content_tag('div', class: %(#{brand}-checkboxes__item)) do
30
- safe_join(
31
- [
32
- input,
33
- label_element.html,
34
- hint_element.html,
35
- ]
36
- )
37
- end,
38
- @conditional_content
39
- ]
40
- )
27
+ safe_join([check_box, @conditional_content])
41
28
  end
42
29
 
43
30
  private
44
31
 
32
+ def check_box
33
+ content_tag('div', class: %(#{brand}-checkboxes__item)) do
34
+ safe_join([input, label_element, hint_element])
35
+ end
36
+ end
37
+
45
38
  def input
46
- @builder.check_box(
47
- @attribute_name,
48
- {
49
- id: field_id(link_errors: @link_errors),
50
- class: check_box_classes,
51
- multiple: @multiple,
52
- aria: { describedby: hint_id },
53
- data: { 'aria-controls' => @conditional_id }
54
- },
55
- @value,
56
- false
57
- )
39
+ @builder.check_box(@attribute_name, input_options, @value, false)
40
+ end
41
+
42
+ def input_options
43
+ {
44
+ id: field_id(link_errors: @link_errors),
45
+ class: check_box_classes,
46
+ multiple: @multiple,
47
+ aria: { describedby: hint_id },
48
+ data: { 'aria-controls' => @conditional_id }
49
+ }
58
50
  end
59
51
 
60
52
  def label_element
61
- @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, checkbox: true, value: @value, link_errors: @link_errors, **label_args)
53
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, checkbox: true, value: @value, link_errors: @link_errors, **label_options)
62
54
  end
63
55
 
64
56
  def hint_element
@@ -22,22 +22,19 @@ module GOVUKDesignSystemFormBuilder
22
22
  def html
23
23
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
24
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(
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
- )
25
+ safe_join([supplemental_content, hint_element, error_element, date])
35
26
  end
36
27
  end
37
28
  end
38
29
 
39
30
  private
40
31
 
32
+ def date
33
+ content_tag('div', class: %(#{brand}-date-input)) do
34
+ safe_join([day, month, year])
35
+ end
36
+ end
37
+
41
38
  def omit_day?
42
39
  @omit_day
43
40
  end
@@ -45,18 +42,18 @@ module GOVUKDesignSystemFormBuilder
45
42
  def day
46
43
  return nil if omit_day?
47
44
 
48
- date_input_item(:day, link_errors: true)
45
+ date_part_input(:day, link_errors: true)
49
46
  end
50
47
 
51
48
  def month
52
- date_input_item(:month, link_errors: omit_day?)
49
+ date_part_input(:month, link_errors: omit_day?)
53
50
  end
54
51
 
55
52
  def year
56
- date_input_item(:year, width: 4)
53
+ date_part_input(:year, width: 4)
57
54
  end
58
55
 
59
- def date_input_item(segment, width: 2, link_errors: false)
56
+ def date_part_input(segment, width: 2, link_errors: false)
60
57
  value = @builder.object.try(@attribute_name).try(segment)
61
58
 
62
59
  content_tag('div', class: %w(date-input__item).prefix(brand)) do
@@ -65,14 +62,14 @@ module GOVUKDesignSystemFormBuilder
65
62
  [
66
63
  tag.label(
67
64
  segment.capitalize,
68
- class: date_input_label_classes,
69
- for: date_attribute_id(segment, link_errors)
65
+ class: date_part_label_classes,
66
+ for: date_part_attribute_id(segment, link_errors)
70
67
  ),
71
68
 
72
69
  tag.input(
73
- id: date_attribute_id(segment, link_errors),
74
- class: date_input_classes(width),
75
- name: date_attribute_name(segment),
70
+ id: date_part_attribute_id(segment, link_errors),
71
+ class: date_part_input_classes(width),
72
+ name: date_part_attribute_name(segment),
76
73
  type: 'text',
77
74
  pattern: '[0-9]*',
78
75
  inputmode: 'numeric',
@@ -85,21 +82,21 @@ module GOVUKDesignSystemFormBuilder
85
82
  end
86
83
  end
87
84
 
88
- def date_input_classes(width)
85
+ def date_part_input_classes(width)
89
86
  %w(input date-input__input).prefix(brand).tap do |classes|
90
87
  classes.push(%(#{brand}-input--width-#{width}))
91
88
  classes.push(%(#{brand}-input--error)) if has_errors?
92
89
  end
93
90
  end
94
91
 
95
- def date_input_label_classes
92
+ def date_part_label_classes
96
93
  %w(label date-input__label).prefix(brand)
97
94
  end
98
95
 
99
96
  # if the field has errors we want the govuk_error_summary to
100
97
  # be able to link to the day field. Otherwise, generate IDs
101
98
  # in the normal fashion
102
- def date_attribute_id(segment, link_errors)
99
+ def date_part_attribute_id(segment, link_errors)
103
100
  if has_errors? && link_errors
104
101
  field_id(link_errors: link_errors)
105
102
  else
@@ -107,7 +104,7 @@ module GOVUKDesignSystemFormBuilder
107
104
  end
108
105
  end
109
106
 
110
- def date_attribute_name(segment)
107
+ def date_part_attribute_name(segment)
111
108
  format(
112
109
  "%<object_name>s[%<attribute_name>s(%<segment>s)]",
113
110
  object_name: @object_name,
@@ -13,16 +13,17 @@ 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([error_prefix, error_message])
22
17
  end
23
18
  end
24
19
 
25
- def message
20
+ private
21
+
22
+ def error_prefix
23
+ tag.span('Error: ', class: %(#{brand}-visually-hidden))
24
+ end
25
+
26
+ def error_message
26
27
  @builder.object.errors.messages[@attribute_name]&.first
27
28
  end
28
29
  end
@@ -12,43 +12,40 @@ module GOVUKDesignSystemFormBuilder
12
12
  def html
13
13
  return nil unless object_has_errors?
14
14
 
15
- content_tag('div', class: summary_class, **error_summary_attributes) do
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: 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 error_list_item(attribute, message)
36
- content_tag('li') do
37
- link_to(
38
- message,
39
- same_page_link(field_id(attribute)),
40
- data: {
41
- turbolinks: false
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 summary_class(part = nil)
48
+ def error_summary_class(part = nil)
52
49
  if part
53
50
  %(#{brand}-error-summary).concat('__', part)
54
51
  else
@@ -68,7 +65,7 @@ module GOVUKDesignSystemFormBuilder
68
65
  @builder.object.errors.any?
69
66
  end
70
67
 
71
- def error_summary_attributes
68
+ def error_summary_options
72
69
  {
73
70
  tabindex: -1,
74
71
  role: 'alert',
@@ -8,37 +8,35 @@ 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:, **extra_args, &block)
11
+ def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, **kwargs, &block)
12
12
  super(builder, object_name, attribute_name, &block)
13
13
 
14
- @label = label
15
- @caption = caption
16
- @hint_text = hint_text
17
- @extra_args = extra_args
14
+ @label = label
15
+ @caption = caption
16
+ @hint_text = hint_text
17
+ @extra_options = kwargs
18
18
  end
19
19
 
20
20
  def html
21
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
+ safe_join([label_element, supplemental_content, hint_element, error_element, file])
37
23
  end
38
24
  end
39
25
 
40
26
  private
41
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
+
42
40
  def file_classes
43
41
  %w(file-upload).prefix(brand).tap do |c|
44
42
  c.push(%(#{brand}-file-upload--error)) if has_errors?
@@ -24,10 +24,7 @@ module GOVUKDesignSystemFormBuilder
24
24
  private
25
25
 
26
26
  def hint_text(supplied)
27
- [
28
- supplied.presence,
29
- localised_text(:hint)
30
- ].compact.first
27
+ [supplied.presence, localised_text(:hint)].compact.first
31
28
  end
32
29
 
33
30
  def hint_classes
@@ -29,21 +29,16 @@ 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)) { build_label }
32
+ content_tag(@tag, class: %(#{brand}-label-wrapper)) { label }
33
33
  else
34
- build_label
34
+ label
35
35
  end
36
36
  end
37
37
 
38
38
  private
39
39
 
40
- def build_label
41
- @builder.label(
42
- @attribute_name,
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
40
+ def label
41
+ @builder.label(@attribute_name, label_options) do
47
42
  @content || safe_join([caption_element.html, @text])
48
43
  end
49
44
  end
@@ -58,6 +53,14 @@ module GOVUKDesignSystemFormBuilder
58
53
  end
59
54
  end
60
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
+
61
64
  def radio_class(radio)
62
65
  radio ? %(#{brand}-radios__label) : nil
63
66
  end
@@ -25,37 +25,38 @@ module GOVUKDesignSystemFormBuilder
25
25
  def html
26
26
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
27
27
  Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id]).html do
28
- safe_join(
29
- [
30
- supplemental_content.html,
31
- hint_element.html,
32
- error_element.html,
33
- Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
34
- safe_join(build_collection)
35
- end
36
- ]
37
- )
28
+ safe_join([supplemental_content, hint_element, error_element, radios])
38
29
  end
39
30
  end
40
31
  end
41
32
 
42
33
  private
43
34
 
44
- def build_collection
35
+ def radios
36
+ Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
37
+ safe_join(collection)
38
+ end
39
+ end
40
+
41
+ def collection
45
42
  @collection.map.with_index do |item, i|
46
- Elements::Radios::CollectionRadioButton.new(
47
- @builder,
48
- @object_name,
49
- @attribute_name,
50
- item,
51
- value_method: @value_method,
52
- text_method: @text_method,
53
- hint_method: @hint_method,
54
- link_errors: has_errors? && i.zero?,
55
- bold_labels: @bold_labels
56
- ).html
43
+ Elements::Radios::CollectionRadioButton.new(@builder, @object_name, @attribute_name, item, **collection_options(i)).html
57
44
  end
58
45
  end
46
+
47
+ def collection_options(index)
48
+ {
49
+ value_method: @value_method,
50
+ text_method: @text_method,
51
+ hint_method: @hint_method,
52
+ link_errors: link_errors?(index),
53
+ bold_labels: @bold_labels
54
+ }
55
+ end
56
+
57
+ def link_errors?(index)
58
+ has_errors? && index.zero?
59
+ end
59
60
  end
60
61
  end
61
62
  end
@@ -24,24 +24,24 @@ module GOVUKDesignSystemFormBuilder
24
24
 
25
25
  def html
26
26
  content_tag('div', class: %(#{brand}-radios__item)) do
27
- safe_join(
28
- [
29
- @builder.radio_button(
30
- @attribute_name,
31
- @value,
32
- id: field_id(link_errors: @link_errors),
33
- aria: { describedby: hint_id },
34
- class: %w(radios__input).prefix(brand)
35
- ),
36
- label_element.html,
37
- hint_element.html
38
- ]
39
- )
27
+ safe_join([radio, label_element, hint_element])
40
28
  end
41
29
  end
42
30
 
43
31
  private
44
32
 
33
+ def radio
34
+ @builder.radio_button(@attribute_name, @value, **radio_options)
35
+ end
36
+
37
+ def radio_options
38
+ {
39
+ id: field_id(link_errors: @link_errors),
40
+ aria: { describedby: hint_id },
41
+ class: %w(radios__input).prefix(brand)
42
+ }
43
+ end
44
+
45
45
  def hint_element
46
46
  @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text, @value, radio: true)
47
47
  end
@@ -23,26 +23,19 @@ module GOVUKDesignSystemFormBuilder
23
23
  end
24
24
 
25
25
  def html
26
- safe_join(
27
- [
28
- content_tag('div', class: %(#{brand}-radios__item)) do
29
- safe_join(
30
- [
31
- input,
32
- label_element.html,
33
- hint_element.html,
34
- ]
35
- )
36
- end,
37
- @conditional_content
38
- ]
39
- )
26
+ safe_join([radio, @conditional_content])
40
27
  end
41
28
 
42
29
  private
43
30
 
31
+ def radio
32
+ content_tag('div', class: %(#{brand}-radios__item)) do
33
+ safe_join([input, label_element, hint_element])
34
+ end
35
+ end
36
+
44
37
  def label_element
45
- @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, radio: true, value: @value, link_errors: @link_errors, **label_args)
38
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, radio: true, value: @value, link_errors: @link_errors, **label_options)
46
39
  end
47
40
 
48
41
  def hint_element
@@ -50,14 +43,16 @@ module GOVUKDesignSystemFormBuilder
50
43
  end
51
44
 
52
45
  def input
53
- @builder.radio_button(
54
- @attribute_name,
55
- @value,
46
+ @builder.radio_button(@attribute_name, @value, input_options)
47
+ end
48
+
49
+ def input_options
50
+ {
56
51
  id: field_id(link_errors: @link_errors),
57
52
  aria: { describedby: hint_id },
58
53
  data: { 'aria-controls' => @conditional_id },
59
54
  class: %w(radios__input).prefix(brand)
60
- )
55
+ }
61
56
  end
62
57
 
63
58
  def conditional_classes
@@ -23,28 +23,17 @@ module GOVUKDesignSystemFormBuilder
23
23
 
24
24
  def html
25
25
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
26
- safe_join(
27
- [
28
- label_element.html,
29
- supplemental_content.html,
30
- hint_element.html,
31
- error_element.html,
32
- @builder.collection_select(
33
- @attribute_name,
34
- @collection,
35
- @value_method,
36
- @text_method,
37
- @options,
38
- build_html_options
39
- )
40
- ]
41
- )
26
+ safe_join([label_element, supplemental_content, hint_element, error_element, select])
42
27
  end
43
28
  end
44
29
 
45
30
  private
46
31
 
47
- def build_html_options
32
+ def select
33
+ @builder.collection_select(@attribute_name, @collection, @value_method, @text_method, @options, select_options)
34
+ end
35
+
36
+ def select_options
48
37
  @html_options.deep_merge(
49
38
  id: field_id(link_errors: true),
50
39
  class: select_classes,
@@ -3,7 +3,7 @@ module GOVUKDesignSystemFormBuilder
3
3
  class Submit < Base
4
4
  using PrefixableArray
5
5
 
6
- def initialize(builder, text, warning:, secondary:, classes:, prevent_double_click:, validate:, &block)
6
+ def initialize(builder, text, warning:, secondary:, classes:, prevent_double_click:, validate:, disabled:, &block)
7
7
  fail ArgumentError, 'buttons can be warning or secondary' if warning && secondary
8
8
 
9
9
  @builder = builder
@@ -13,29 +13,35 @@ module GOVUKDesignSystemFormBuilder
13
13
  @secondary = secondary
14
14
  @classes = classes
15
15
  @validate = validate
16
+ @disabled = disabled
16
17
  @block_content = capture { block.call } if block_given?
17
18
  end
18
19
 
19
20
  def html
20
- safe_join(
21
- [
22
- @builder.submit(
23
- @text,
24
- class: %w(button).prefix(brand).push(
25
- warning_class,
26
- secondary_class,
27
- @classes,
28
- padding_class(@block_content.present?)
29
- ).compact,
30
- **extra_args
31
- ),
32
- @block_content
33
- ]
34
- )
21
+ safe_join([submit, @block_content])
35
22
  end
36
23
 
37
24
  private
38
25
 
26
+ def submit
27
+ @builder.submit(@text, class: submit_classes, **submit_options)
28
+ end
29
+
30
+ def submit_classes
31
+ %w(button).prefix(brand).push(warning_class, secondary_class, disabled_class, @classes, padding_class(@block_content.present?))
32
+ end
33
+
34
+ def submit_options
35
+ {
36
+ formnovalidate: !@validate,
37
+ disabled: @disabled,
38
+ data: {
39
+ module: %(#{brand}-button),
40
+ 'prevent-double-click': @prevent_double_click
41
+ }.select { |_k, v| v.present? }
42
+ }
43
+ end
44
+
39
45
  def warning_class
40
46
  %(#{brand}-button--warning) if @warning
41
47
  end
@@ -48,13 +54,8 @@ module GOVUKDesignSystemFormBuilder
48
54
  %(#{brand}-!-margin-right-1) if content_present
49
55
  end
50
56
 
51
- def extra_args
52
- {
53
- formnovalidate: !@validate,
54
- data: {
55
- module: %(#{brand}-button), 'prevent-double-click' => @prevent_double_click
56
- }.select { |_k, v| v.present? }
57
- }
57
+ def disabled_class
58
+ %(#{brand}-button--disabled) if @disabled
58
59
  end
59
60
  end
60
61
  end
@@ -8,13 +8,13 @@ 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:, rows:, max_words:, max_chars:, threshold:, **extra_args, &block)
11
+ def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, rows:, max_words:, max_chars:, threshold:, **kwargs, &block)
12
12
  super(builder, object_name, attribute_name, &block)
13
13
 
14
14
  @label = label
15
15
  @caption = caption
16
16
  @hint_text = hint_text
17
- @extra_args = extra_args
17
+ @attributes = kwargs
18
18
  @max_words = max_words
19
19
  @max_chars = max_chars
20
20
  @threshold = threshold
@@ -24,39 +24,32 @@ module GOVUKDesignSystemFormBuilder
24
24
  def html
25
25
  Containers::CharacterCount.new(@builder, max_words: @max_words, max_chars: @max_chars, threshold: @threshold).html do
26
26
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
27
- safe_join(
28
- [
29
- [
30
- label_element,
31
- supplemental_content,
32
- hint_element,
33
- error_element
34
- ].map(&:html),
35
- @builder.text_area(
36
- @attribute_name,
37
- id: field_id(link_errors: true),
38
- class: govuk_textarea_classes,
39
- aria: {
40
- describedby: described_by(hint_id, error_id, supplemental_id, limit_description_id)
41
- },
42
- **@extra_args.merge(rows: @rows)
43
- ),
44
- limit_description
45
- ].flatten.compact
46
- )
27
+ safe_join([label_element, supplemental_content, hint_element, error_element, text_area, limit_description])
47
28
  end
48
29
  end
49
30
  end
50
31
 
51
32
  private
52
33
 
53
- def govuk_textarea_classes
34
+ def text_area
35
+ @builder.text_area(@attribute_name, **text_area_options, **@attributes.merge(rows: @rows))
36
+ end
37
+
38
+ def text_area_classes
54
39
  %w(textarea).prefix(brand).tap do |classes|
55
40
  classes.push(%(#{brand}-textarea--error)) if has_errors?
56
41
  classes.push(%(#{brand}-js-character-count)) if limit?
57
42
  end
58
43
  end
59
44
 
45
+ def text_area_options
46
+ {
47
+ id: field_id(link_errors: true),
48
+ class: text_area_classes,
49
+ aria: { describedby: described_by(hint_id, error_id, supplemental_id, limit_description_id) },
50
+ }
51
+ end
52
+
60
53
  # Provides an id for use by the textual description of character and word limits.
61
54
  #
62
55
  # @note In order for the GOV.UK Frontend JavaScript to pick up this associated field
@@ -4,12 +4,11 @@ module GOVUKDesignSystemFormBuilder
4
4
  private
5
5
 
6
6
  def caption_element
7
- @caption_element ||= Elements::Caption.new(
8
- @builder,
9
- @object_name,
10
- @attribute_name,
11
- **{ text: nil }.merge({ text: caption_text, size: caption_size }.compact)
12
- )
7
+ @caption_element ||= Elements::Caption.new(@builder, @object_name, @attribute_name, **caption_options)
8
+ end
9
+
10
+ def caption_options
11
+ { text: nil }.merge({ text: caption_text, size: caption_size }.compact)
13
12
  end
14
13
 
15
14
  def caption_text
@@ -1,45 +1,36 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Traits
3
3
  module Input
4
- def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, width:, **extra_args, &block)
4
+ def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, width:, **kwargs, &block)
5
5
  super(builder, object_name, attribute_name, &block)
6
6
 
7
- @width = width
8
- @extra_args = extra_args
9
- @label = label
10
- @caption = caption
11
- @hint_text = hint_text
7
+ @width = width
8
+ @attributes = kwargs
9
+ @label = label
10
+ @caption = caption
11
+ @hint_text = hint_text
12
12
  end
13
13
 
14
14
  def html
15
15
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
16
- safe_join(
17
- [
18
- label_element.html,
19
- supplemental_content.html,
20
- hint_element.html,
21
- error_element.html,
22
- @builder.send(
23
- builder_method,
24
- @attribute_name,
25
- id: field_id(link_errors: true),
26
- class: input_classes,
27
- aria: {
28
- describedby: described_by(
29
- hint_id,
30
- error_id,
31
- supplemental_id
32
- )
33
- },
34
- **@extra_args
35
- )
36
- ]
37
- )
16
+ safe_join([label_element, supplemental_content, hint_element, error_element, input])
38
17
  end
39
18
  end
40
19
 
41
20
  private
42
21
 
22
+ def input
23
+ @builder.send(builder_method, @attribute_name, **input_options.merge(@attributes))
24
+ end
25
+
26
+ def input_options
27
+ {
28
+ id: field_id(link_errors: true),
29
+ class: input_classes,
30
+ aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
31
+ }
32
+ end
33
+
43
34
  def input_classes
44
35
  [%(#{brand}-input)].push(width_classes, error_classes).compact
45
36
  end
@@ -4,10 +4,10 @@ module GOVUKDesignSystemFormBuilder
4
4
  private
5
5
 
6
6
  def label_element
7
- @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, caption: @caption, **label_args)
7
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, caption: @caption, **label_options)
8
8
  end
9
9
 
10
- def label_args
10
+ def label_options
11
11
  case @label
12
12
  when Hash
13
13
  @label
@@ -1,3 +1,3 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
- VERSION = '1.2.0'.freeze
2
+ VERSION = '1.2.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_design_system_formbuilder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-06 00:00:00.000000000 Z
11
+ date: 2020-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -84,22 +84,22 @@ dependencies:
84
84
  name: pry-byebug
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: 3.9.0
90
87
  - - "~>"
91
88
  - !ruby/object:Gem::Version
92
89
  version: '3.9'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 3.9.0
93
93
  type: :development
94
94
  prerelease: false
95
95
  version_requirements: !ruby/object:Gem::Requirement
96
96
  requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- version: 3.9.0
100
97
  - - "~>"
101
98
  - !ruby/object:Gem::Version
102
99
  version: '3.9'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 3.9.0
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: rspec-html-matchers
105
105
  requirement: !ruby/object:Gem::Requirement
@@ -317,7 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
317
317
  - !ruby/object:Gem::Version
318
318
  version: '0'
319
319
  requirements: []
320
- rubygems_version: 3.0.3
320
+ rubygems_version: 3.1.2
321
321
  signing_key:
322
322
  specification_version: 4
323
323
  summary: GOV.UK-compliant Rails form builder