govuk_design_system_formbuilder 1.2.0 → 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.
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