govuk_design_system_formbuilder 2.6.0 → 2.7.3

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +22 -8
  3. data/lib/govuk_design_system_formbuilder/base.rb +1 -1
  4. data/lib/govuk_design_system_formbuilder/builder.rb +30 -7
  5. data/lib/govuk_design_system_formbuilder/containers/check_boxes.rb +1 -1
  6. data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +2 -1
  7. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +1 -1
  8. data/lib/govuk_design_system_formbuilder/containers/form_group.rb +1 -1
  9. data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +3 -2
  10. data/lib/govuk_design_system_formbuilder/containers/radios.rb +1 -1
  11. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +11 -4
  12. data/lib/govuk_design_system_formbuilder/elements/check_boxes/label.rb +5 -1
  13. data/lib/govuk_design_system_formbuilder/elements/collection_select.rb +1 -1
  14. data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +17 -4
  15. data/lib/govuk_design_system_formbuilder/elements/file.rb +1 -1
  16. data/lib/govuk_design_system_formbuilder/elements/inputs/number.rb +2 -0
  17. data/lib/govuk_design_system_formbuilder/elements/inputs/password.rb +2 -0
  18. data/lib/govuk_design_system_formbuilder/elements/inputs/phone.rb +2 -0
  19. data/lib/govuk_design_system_formbuilder/elements/inputs/text.rb +2 -0
  20. data/lib/govuk_design_system_formbuilder/elements/inputs/url.rb +2 -0
  21. data/lib/govuk_design_system_formbuilder/elements/label.rb +1 -1
  22. data/lib/govuk_design_system_formbuilder/elements/legend.rb +1 -1
  23. data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +2 -2
  24. data/lib/govuk_design_system_formbuilder/elements/select.rb +1 -1
  25. data/lib/govuk_design_system_formbuilder/elements/submit.rb +14 -2
  26. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +1 -1
  27. data/lib/govuk_design_system_formbuilder/presenters/error_summary.rb +29 -0
  28. data/lib/govuk_design_system_formbuilder/traits/fieldset_item.rb +4 -4
  29. data/lib/govuk_design_system_formbuilder/traits/html_attributes.rb +1 -1
  30. data/lib/govuk_design_system_formbuilder/traits/input.rb +1 -1
  31. data/lib/govuk_design_system_formbuilder/traits/select.rb +1 -1
  32. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  33. data/lib/govuk_design_system_formbuilder.rb +16 -5
  34. metadata +5 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd0f0c49f266a8cb411ebed4833b6284cc8cc4b6acd8ce3bf87d705feb40062b
4
- data.tar.gz: b2659204e304dd40ed2254d06f43acdd4b5b5f13fc48d180741645d004c15719
3
+ metadata.gz: 8dde478d08a40d1cc871b7f0b2db7180db591ec384d4d7cc160ce9523605d8f2
4
+ data.tar.gz: f406bfbc2ac3b5eb5a5ce5c6cade4138459323a6a9fe9e8cbe23dcf33edcd9cb
5
5
  SHA512:
6
- metadata.gz: 962d77c5cc9b3501f0b8efab08a9f7c930d3aed9b28e96e06bd4e9851fd00586eb557a43150f6b911c7ad5044d0cc4e0bc08027697faf223aa70ce0765558898
7
- data.tar.gz: 8af398e7d5673dd8b8b5f25810d88afb281a297f409c5883d567fd13a9f0347cbe644c2f32f6e69b1ec8a0e261ad81abf723e444d6186bdfb7f9901431f70c10
6
+ metadata.gz: 112918eb62e62548f16a27cb8e3a33e353d4be9543819f366f88671e628faff90a4ec28fb49a4a76d0d8ed0136569db090a36091c1cf6e1e3e0f360e770939c4
7
+ data.tar.gz: ae6d8df17006b0a5d77eb6bd21d8402f53eca1087c34071c39534ca8e9753e33a6ca555f242eadf2a83e6eeaa4cbc92689e19458351851ba408cf4b419b656e3
data/README.md CHANGED
@@ -1,15 +1,14 @@
1
1
  # GOV.UK Design System Form Builder for Rails
2
2
 
3
- [![Tests](https://github.com/DFE-Digital/govuk_design_system_formbuilder/workflows/Tests/badge.svg)](https://github.com/DFE-Digital/govuk_design_system_formbuilder/actions)
4
- [![Maintainability](https://api.codeclimate.com/v1/badges/fde73b5dc9476197281b/maintainability)](https://codeclimate.com/github/DFE-Digital/govuk_design_system_formbuilder/maintainability)
3
+ [![Tests](https://github.com/DFE-Digital/govuk-formbuilder/workflows/Tests/badge.svg)](https://github.com/DFE-Digital/govuk-formbuilder/actions)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/110136fb22341d3ba646/maintainability)](https://codeclimate.com/github/DFE-Digital/govuk-formbuilder/maintainability)
5
5
  [![Gem Version](https://badge.fury.io/rb/govuk_design_system_formbuilder.svg)](https://badge.fury.io/rb/govuk_design_system_formbuilder)
6
6
  [![Gem](https://img.shields.io/gem/dt/govuk_design_system_formbuilder?logo=rubygems)](https://rubygems.org/gems/govuk_design_system_formbuilder)
7
- [![Test Coverage](https://api.codeclimate.com/v1/badges/fde73b5dc9476197281b/test_coverage)](https://codeclimate.com/github/DFE-Digital/govuk_design_system_formbuilder/test_coverage)
8
- [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=DFE-Digital/govuk_design_system_formbuilder)](https://dependabot.com)
9
- [![GitHub license](https://img.shields.io/github/license/DFE-Digital/govuk_design_system_formbuilder)](https://github.com/DFE-Digital/govuk_design_system_formbuilder/blob/master/LICENSE)
10
- [![GOV.UK Design System Version](https://img.shields.io/badge/GOV.UK%20Design%20System-3.12.0-brightgreen)](https://design-system.service.gov.uk)
11
- [![Rails](https://img.shields.io/badge/Ruby-2.6.7%20%E2%95%B1%202.7.3%20%E2%95%B1%203.0.1-E16D6D)](https://www.ruby-lang.org/en/downloads/)
12
- [![Ruby](https://img.shields.io/badge/Rails-6.0.3.7%20%E2%95%B1%206.1.3.2-E16D6D)](https://weblog.rubyonrails.org/releases/)
7
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/110136fb22341d3ba646/test_coverage)](https://codeclimate.com/github/DFE-Digital/govuk-formbuilder/test_coverage)
8
+ [![GitHub license](https://img.shields.io/github/license/DFE-Digital/govuk_design_system_formbuilder)](https://github.com/DFE-Digital/govuk-formbuilder/blob/master/LICENSE)
9
+ [![GOV.UK Design System Version](https://img.shields.io/badge/GOV.UK%20Design%20System-3.13.0-brightgreen)](https://design-system.service.gov.uk)
10
+ [![Rails](https://img.shields.io/badge/Ruby-2.6.8%20%E2%95%B1%202.7.4%20%E2%95%B1%203.0.2-E16D6D)](https://www.ruby-lang.org/en/downloads/)
11
+ [![Ruby](https://img.shields.io/badge/Rails-6.0.4%20%E2%95%B1%206.1.3.2-E16D6D)](https://weblog.rubyonrails.org/releases/)
13
12
 
14
13
  This library provides an easy-to-use form builder for the [GOV.UK Design System](https://design-system.service.gov.uk/).
15
14
 
@@ -129,6 +128,21 @@ To help keep the logs clean and tidy, please configure git to use your full name
129
128
  git config --global user.name "Julius Hibbert"
130
129
  ```
131
130
 
131
+ ## Services using this library
132
+
133
+ Approximately [40 services use this library](https://github.com/DFE-Digital/govuk-formbuilder/network/dependents),
134
+ here are a few from the <abbr title="Department for Education">DfE</abbr>, <abbr title="Ministry of Justice">MoJ</abbr>, and
135
+ <abbr title="Department for Business, Energy & Industrial Strategy">BEIS</abbr>.
136
+
137
+ * [Apply for teacher training](https://www.github.com/DFE-Digital/apply-for-teacher-training)
138
+ * [Teaching Vacancies](https://www.github.com/DFE-Digital/teaching-vacancies)
139
+ * [Get a teacher training adviser](https://www.github.com/DFE-Digital/get-teacher-training-adviser-service/)
140
+ * [Claim for crown court defence](https://www.github.com/ministryofjustice/Claim-for-Crown-Court-Defence)
141
+ * [Appeal to the tax tribunal](https://www.github.com/ministryofjustice/tax-tribunals-datacapture)
142
+ * [Apply to court about child arrangements](https://www.github.com/ministryofjustice/c100-application)
143
+ * [Trade Tariff duty calculator](https://www.github.com/trade-tariff/trade-tariff-duty-calculator)
144
+ * [Report your official development assistance](https://www.github.com/UKGovernmentBEIS/beis-report-official-development-assistance)
145
+
132
146
  ## Thanks 👩🏽‍⚖️
133
147
 
134
148
  This project was inspired by [Ministry of Justice's GovukElementsFormBuilder](https://github.com/ministryofjustice/govuk_elements_form_builder),
@@ -57,7 +57,7 @@ module GOVUKDesignSystemFormBuilder
57
57
  @builder.object.errors.messages[@attribute_name].present?
58
58
  end
59
59
 
60
- def described_by(*ids)
60
+ def combine_references(*ids)
61
61
  ids.flatten.compact
62
62
  end
63
63
 
@@ -813,6 +813,8 @@ module GOVUKDesignSystemFormBuilder
813
813
  # @option label hidden [Boolean] control the visability of the label. Hidden labels will stil be read by screenreaders
814
814
  # @option label kwargs [Hash] additional arguments are applied as attributes on the +label+ element
815
815
  # @param multiple [Boolean] controls whether the check box is part of a collection or represents a single attribute
816
+ # @param exclusive [Boolean] sets the checkbox so that when checked none of its siblings can be too. Usually
817
+ # used for the 'None of these apply to me' option found beneath a {#govuk_check_box_divider}.
816
818
  # @option kwargs [Hash] kwargs additional arguments are applied as attributes to the +input+ element
817
819
  # @param block [Block] any HTML passed in will form the contents of the fieldset
818
820
  # @return [ActiveSupport::SafeBuffer] HTML output
@@ -825,7 +827,7 @@ module GOVUKDesignSystemFormBuilder
825
827
  # label: { text: 'Do you agree with our terms and conditions?' },
826
828
  # hint: { text: 'You will not be able to proceed unless you do' }
827
829
  #
828
- def govuk_check_box(attribute_name, value, unchecked_value = false, hint: {}, label: {}, link_errors: false, multiple: true, **kwargs, &block)
830
+ def govuk_check_box(attribute_name, value, unchecked_value = false, hint: {}, label: {}, link_errors: false, multiple: true, exclusive: false, **kwargs, &block)
829
831
  Elements::CheckBoxes::FieldsetCheckBox.new(
830
832
  self,
831
833
  object_name,
@@ -836,14 +838,27 @@ module GOVUKDesignSystemFormBuilder
836
838
  label: label,
837
839
  link_errors: link_errors,
838
840
  multiple: multiple,
841
+ exclusive: exclusive,
839
842
  **kwargs,
840
843
  &block
841
844
  ).html
842
845
  end
843
846
 
847
+ # Inserts a text divider into a list of check boxes
848
+ #
849
+ # @param text [String] The divider text
850
+ # @note This should only be used from within a {#govuk_check_boxes_fieldset}
851
+ # @see https://design-system.service.gov.uk/components/checkboxes/#add-an-option-for-none- GOV.UK check boxes with a text divider
852
+ # @return [ActiveSupport::SafeBuffer] HTML output
853
+ # @example A custom divider
854
+ # = govuk_check_box_divider 'On the other hand'
855
+ def govuk_check_box_divider(text = config.default_check_box_divider_text)
856
+ tag.div(text, class: %w(govuk-checkboxes__divider))
857
+ end
858
+
844
859
  # Generates a submit button, green by default
845
860
  #
846
- # @param text [String] the button text
861
+ # @param text [String,Proc] the button text. When a +Proc+ is provided its contents will be rendered within the button element
847
862
  # @param warning [Boolean] makes the button red ({https://design-system.service.gov.uk/components/button/#warning-buttons warning}) when true
848
863
  # @param secondary [Boolean] makes the button grey ({https://design-system.service.gov.uk/components/button/#secondary-buttons secondary}) when true
849
864
  # @param classes [Array,String] Classes to add to the submit button
@@ -853,7 +868,7 @@ module GOVUKDesignSystemFormBuilder
853
868
  # client-side validation provided by the browser. This is to provide a more consistent and accessible user
854
869
  # experience
855
870
  # @param disabled [Boolean] makes the button disabled when true
856
- # @option kwargs [Hash] kwargs additional arguments are applied as attributes to the +input+ element
871
+ # @option kwargs [Hash] kwargs additional arguments are applied as attributes to the +button+ element
857
872
  # @param block [Block] When content is passed in via a block the submit element and the block content will
858
873
  # be wrapped in a +<div class="govuk-button-group">+ which will space the buttons and links within
859
874
  # evenly.
@@ -861,8 +876,9 @@ module GOVUKDesignSystemFormBuilder
861
876
  # @return [ActiveSupport::SafeBuffer] HTML output
862
877
  # @note Only the first additional button or link (passed in via a block) will be given the
863
878
  # correct left margin, subsequent buttons will need to be manually accounted for
864
- # @note This helper always renders an +<input type='submit'>+ tag, HTML content is not supported inside. You
865
- # can place +<button>+ tags inside the form to have the same effect
879
+ # @note This helper always renders an +<button type='submit'>+ tag. Previous versions of this gem rendered
880
+ # a +`<input type='submit'>' tag instead, but there is a {https://github.com/alphagov/govuk_elements/issues/545 longstanding bug}
881
+ # with this approach where the top few pixels don't initiate a submission when clicked.
866
882
  # @see https://design-system.service.gov.uk/components/button/#stop-users-from-accidentally-sending-information-more-than-once
867
883
  # GOV.UK double click prevention
868
884
  #
@@ -935,6 +951,13 @@ module GOVUKDesignSystemFormBuilder
935
951
  # which they were defined on the model).
936
952
  # @option kwargs [Hash] kwargs additional arguments are applied as attributes to the error summary +div+ element
937
953
  # @param block [Block] arbitrary HTML that will be rendered between title and error message list
954
+ # @param presenter [Class,Object] the class or object that is responsible for formatting a list of error
955
+ # messages that will be rendered in the summary.
956
+ #
957
+ # * When a class is specified it will be instantiated with the object's errors in the +object.errors.messages+ format.
958
+ # * When an object is specified it will be used as-is.
959
+ #
960
+ # The object must implement +#formatted_error_messages+, see {Presenters::ErrorSummaryPresenter} for more details.
938
961
  #
939
962
  # @note Only the first error in the +#errors+ array for each attribute will
940
963
  # be included.
@@ -943,8 +966,8 @@ module GOVUKDesignSystemFormBuilder
943
966
  # = f.govuk_error_summary 'Uh-oh, spaghettios'
944
967
  #
945
968
  # @see https://design-system.service.gov.uk/components/error-summary/ GOV.UK error summary
946
- def govuk_error_summary(title = config.default_error_summary_title, link_base_errors_to: nil, order: nil, **kwargs, &block)
947
- Elements::ErrorSummary.new(self, object_name, title, link_base_errors_to: link_base_errors_to, order: order, **kwargs, &block).html
969
+ def govuk_error_summary(title = config.default_error_summary_title, presenter: config.default_error_summary_presenter, link_base_errors_to: nil, order: nil, **kwargs, &block)
970
+ Elements::ErrorSummary.new(self, object_name, title, link_base_errors_to: link_base_errors_to, order: order, presenter: presenter, **kwargs, &block).html
948
971
  end
949
972
 
950
973
  # Generates a fieldset containing the contents of the block
@@ -22,7 +22,7 @@ module GOVUKDesignSystemFormBuilder
22
22
  end
23
23
 
24
24
  def classes
25
- [%(#{brand}-checkboxes), small_class, custom_classes].flatten.compact
25
+ combine_references(%(#{brand}-checkboxes), small_class, custom_classes)
26
26
  end
27
27
 
28
28
  def small_class
@@ -5,6 +5,8 @@ module GOVUKDesignSystemFormBuilder
5
5
  include Traits::Hint
6
6
 
7
7
  def initialize(builder, object_name, attribute_name, hint:, legend:, caption:, small:, classes:, form_group:, multiple:, &block)
8
+ fail LocalJumpError, 'no block given' unless block_given?
9
+
8
10
  super(builder, object_name, attribute_name, &block)
9
11
 
10
12
  @legend = legend
@@ -14,7 +16,6 @@ module GOVUKDesignSystemFormBuilder
14
16
  @classes = classes
15
17
  @form_group = form_group
16
18
  @multiple = multiple
17
- @block_content = capture { block.call }
18
19
  end
19
20
 
20
21
  def html
@@ -8,7 +8,7 @@ module GOVUKDesignSystemFormBuilder
8
8
 
9
9
  @legend = legend
10
10
  @caption = caption
11
- @described_by = described_by(described_by)
11
+ @described_by = combine_references(described_by)
12
12
  @attribute_name = attribute_name
13
13
  @html_attributes = kwargs
14
14
  end
@@ -15,7 +15,7 @@ module GOVUKDesignSystemFormBuilder
15
15
  private
16
16
 
17
17
  def classes
18
- [form_group_class, error_class, custom_classes].flatten.compact
18
+ combine_references(form_group_class, error_class, custom_classes)
19
19
  end
20
20
 
21
21
  def form_group_class
@@ -5,7 +5,9 @@ module GOVUKDesignSystemFormBuilder
5
5
  include Traits::Error
6
6
 
7
7
  def initialize(builder, object_name, attribute_name, hint:, legend:, caption:, inline:, small:, classes:, form_group:, &block)
8
- super(builder, object_name, attribute_name)
8
+ fail LocalJumpError, 'no block given' unless block_given?
9
+
10
+ super(builder, object_name, attribute_name, &block)
9
11
 
10
12
  @inline = inline
11
13
  @small = small
@@ -14,7 +16,6 @@ module GOVUKDesignSystemFormBuilder
14
16
  @hint = hint
15
17
  @classes = classes
16
18
  @form_group = form_group
17
- @block_content = capture { block.call }
18
19
  end
19
20
 
20
21
  def html
@@ -25,7 +25,7 @@ module GOVUKDesignSystemFormBuilder
25
25
  end
26
26
 
27
27
  def classes
28
- [%(#{brand}-radios), inline_class, small_class, custom_classes].flatten.compact
28
+ combine_references(%(#{brand}-radios), inline_class, small_class, custom_classes)
29
29
  end
30
30
 
31
31
  def inline_class
@@ -7,8 +7,8 @@ module GOVUKDesignSystemFormBuilder
7
7
  include Traits::HTMLAttributes
8
8
  include Traits::FieldsetItem
9
9
 
10
- def initialize(builder, object_name, attribute_name, value, unchecked_value, label:, hint:, link_errors:, multiple:, **kwargs, &block)
11
- super(builder, object_name, attribute_name)
10
+ def initialize(builder, object_name, attribute_name, value, unchecked_value, label:, hint:, link_errors:, multiple:, exclusive:, **kwargs, &block)
11
+ super(builder, object_name, attribute_name, &block)
12
12
 
13
13
  @value = value
14
14
  @unchecked_value = unchecked_value
@@ -17,8 +17,9 @@ module GOVUKDesignSystemFormBuilder
17
17
  @multiple = multiple
18
18
  @link_errors = link_errors
19
19
  @html_attributes = kwargs
20
+ @exclusive = exclusive
20
21
 
21
- conditional_content(&block)
22
+ conditional_content(@block_content)
22
23
  end
23
24
 
24
25
  private
@@ -28,12 +29,18 @@ module GOVUKDesignSystemFormBuilder
28
29
  end
29
30
 
30
31
  def input
31
- @builder.check_box(@attribute_name, attributes(@html_attributes), @value, @unchecked_value)
32
+ @builder.check_box(@attribute_name, attributes(@html_attributes.deep_merge(exclusive_options)), @value, @unchecked_value)
32
33
  end
33
34
 
34
35
  def fieldset_options
35
36
  { checkbox: true }
36
37
  end
38
+
39
+ def exclusive_options
40
+ return {} unless @exclusive
41
+
42
+ { data: { behaviour: 'exclusive' } }
43
+ end
37
44
  end
38
45
  end
39
46
  end
@@ -16,7 +16,7 @@ module GOVUKDesignSystemFormBuilder
16
16
 
17
17
  def html
18
18
  @checkbox.label(for: field_id(link_errors: @link_errors), class: label_classes) do
19
- [localised_text(:label), @checkbox.text, @value].compact.first.to_s
19
+ label_content.to_s
20
20
  end
21
21
  end
22
22
 
@@ -25,6 +25,10 @@ module GOVUKDesignSystemFormBuilder
25
25
  def label_classes
26
26
  %w(label checkboxes__label).prefix(brand)
27
27
  end
28
+
29
+ def label_content
30
+ [localised_text(:label), @checkbox.text, @value].find(&:presence)
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -40,7 +40,7 @@ module GOVUKDesignSystemFormBuilder
40
40
  {
41
41
  id: field_id(link_errors: true),
42
42
  class: classes,
43
- aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
43
+ aria: { describedby: combine_references(hint_id, error_id, supplemental_id) }
44
44
  }
45
45
  end
46
46
 
@@ -4,13 +4,14 @@ module GOVUKDesignSystemFormBuilder
4
4
  include Traits::Error
5
5
  include Traits::HTMLAttributes
6
6
 
7
- def initialize(builder, object_name, title, link_base_errors_to:, order:, **kwargs, &block)
7
+ def initialize(builder, object_name, title, link_base_errors_to:, order:, presenter:, **kwargs, &block)
8
8
  super(builder, object_name, nil, &block)
9
9
 
10
10
  @title = title
11
11
  @link_base_errors_to = link_base_errors_to
12
12
  @html_attributes = kwargs
13
13
  @order = order
14
+ @presenter = presenter
14
15
  end
15
16
 
16
17
  def html
@@ -33,7 +34,17 @@ module GOVUKDesignSystemFormBuilder
33
34
 
34
35
  def list
35
36
  tag.ul(class: [%(#{brand}-list), summary_class('list')]) do
36
- safe_join(error_messages.map { |attribute, messages| list_item(attribute, messages.first) })
37
+ safe_join(presenter.formatted_error_messages.map { |args| list_item(*args) })
38
+ end
39
+ end
40
+
41
+ # If the provided @presenter is a class, instantiate it with the sorted
42
+ # error_messages from our object. Otherwise (if it's any other object),
43
+ # treat it like a presenter
44
+ def presenter
45
+ (@presenter.is_a?(Class) ? @presenter.new(error_messages) : @presenter).tap do |p|
46
+ fail(ArgumentError, "error summary presenter doesn't implement #formatted_error_messages") unless
47
+ p.respond_to?(:formatted_error_messages)
37
48
  end
38
49
  end
39
50
 
@@ -41,8 +52,10 @@ module GOVUKDesignSystemFormBuilder
41
52
  messages = @builder.object.errors.messages
42
53
 
43
54
  if reorder_errors?
44
- return messages.sort_by.with_index(1) do |(attr, _val), i|
45
- error_order.index(attr) || (i + messages.size)
55
+ adjustment = error_order.size + messages.size
56
+
57
+ return messages.sort_by.with_index do |(attr, _val), i|
58
+ error_order.index(attr) || (i + adjustment)
46
59
  end
47
60
  end
48
61
 
@@ -35,7 +35,7 @@ module GOVUKDesignSystemFormBuilder
35
35
  {
36
36
  id: field_id(link_errors: true),
37
37
  class: classes,
38
- aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
38
+ aria: { describedby: combine_references(hint_id, error_id, supplemental_id) }
39
39
  }
40
40
  end
41
41
 
@@ -9,6 +9,8 @@ module GOVUKDesignSystemFormBuilder
9
9
  include Traits::Supplemental
10
10
  include Traits::HTMLAttributes
11
11
 
12
+ private
13
+
12
14
  def builder_method
13
15
  :number_field
14
16
  end
@@ -9,6 +9,8 @@ module GOVUKDesignSystemFormBuilder
9
9
  include Traits::Supplemental
10
10
  include Traits::HTMLAttributes
11
11
 
12
+ private
13
+
12
14
  def builder_method
13
15
  :password_field
14
16
  end
@@ -9,6 +9,8 @@ module GOVUKDesignSystemFormBuilder
9
9
  include Traits::Supplemental
10
10
  include Traits::HTMLAttributes
11
11
 
12
+ private
13
+
12
14
  def builder_method
13
15
  :phone_field
14
16
  end
@@ -9,6 +9,8 @@ module GOVUKDesignSystemFormBuilder
9
9
  include Traits::Supplemental
10
10
  include Traits::HTMLAttributes
11
11
 
12
+ private
13
+
12
14
  def builder_method
13
15
  :text_field
14
16
  end
@@ -9,6 +9,8 @@ module GOVUKDesignSystemFormBuilder
9
9
  include Traits::Supplemental
10
10
  include Traits::HTMLAttributes
11
11
 
12
+ private
13
+
12
14
  def builder_method
13
15
  :url_field
14
16
  end
@@ -50,7 +50,7 @@ module GOVUKDesignSystemFormBuilder
50
50
  end
51
51
 
52
52
  def retrieve_text(option_text, hidden)
53
- text = [option_text, localised_text(:label), @attribute_name.capitalize].compact.first
53
+ text = [option_text, localised_text(:label), @attribute_name.capitalize].find(&:presence)
54
54
 
55
55
  if hidden
56
56
  tag.span(text, class: %(#{brand}-visually-hidden))
@@ -45,7 +45,7 @@ module GOVUKDesignSystemFormBuilder
45
45
  end
46
46
 
47
47
  def retrieve_text(supplied_text)
48
- [supplied_text, localised_text(:legend), @attribute_name&.capitalize].compact.first
48
+ [supplied_text, localised_text(:legend), @attribute_name&.capitalize].find(&:presence)
49
49
  end
50
50
 
51
51
  def classes
@@ -8,7 +8,7 @@ module GOVUKDesignSystemFormBuilder
8
8
  include Traits::FieldsetItem
9
9
 
10
10
  def initialize(builder, object_name, attribute_name, value, label:, hint:, link_errors:, **kwargs, &block)
11
- super(builder, object_name, attribute_name)
11
+ super(builder, object_name, attribute_name, &block)
12
12
 
13
13
  @value = value
14
14
  @label = label
@@ -16,7 +16,7 @@ module GOVUKDesignSystemFormBuilder
16
16
  @link_errors = has_errors? && link_errors
17
17
  @html_attributes = kwargs
18
18
 
19
- conditional_content(&block)
19
+ conditional_content(@block_content)
20
20
  end
21
21
 
22
22
  private
@@ -38,7 +38,7 @@ module GOVUKDesignSystemFormBuilder
38
38
  {
39
39
  id: field_id(link_errors: true),
40
40
  class: classes,
41
- aria: { describedby: described_by(hint_id, error_id) }
41
+ aria: { describedby: combine_references(hint_id, error_id) }
42
42
  }
43
43
  end
44
44
  end
@@ -9,7 +9,7 @@ module GOVUKDesignSystemFormBuilder
9
9
 
10
10
  fail ArgumentError, 'buttons can be warning or secondary' if warning && secondary
11
11
 
12
- @text = text
12
+ @text = build_text(text)
13
13
  @prevent_double_click = prevent_double_click
14
14
  @warning = warning
15
15
  @secondary = secondary
@@ -26,6 +26,17 @@ module GOVUKDesignSystemFormBuilder
26
26
 
27
27
  private
28
28
 
29
+ def build_text(text)
30
+ case text
31
+ when String
32
+ text
33
+ when Proc
34
+ capture { text.call }
35
+ else
36
+ fail(ArgumentError, %(text must be a String or Proc))
37
+ end
38
+ end
39
+
29
40
  def button_group
30
41
  Containers::ButtonGroup.new(@builder, buttons).html
31
42
  end
@@ -35,11 +46,12 @@ module GOVUKDesignSystemFormBuilder
35
46
  end
36
47
 
37
48
  def submit
38
- @builder.submit(@text, **attributes(@html_attributes))
49
+ @builder.tag.button(@text, **attributes(@html_attributes))
39
50
  end
40
51
 
41
52
  def options
42
53
  {
54
+ type: 'submit',
43
55
  formnovalidate: !@validate,
44
56
  disabled: @disabled,
45
57
  class: classes,
@@ -53,7 +53,7 @@ module GOVUKDesignSystemFormBuilder
53
53
  id: field_id(link_errors: true),
54
54
  class: classes,
55
55
  rows: @rows,
56
- aria: { describedby: described_by(hint_id, error_id, supplemental_id, limit_description_id) },
56
+ aria: { describedby: combine_references(hint_id, error_id, supplemental_id, limit_description_id) },
57
57
  }
58
58
  end
59
59
 
@@ -0,0 +1,29 @@
1
+ module Presenters
2
+ # This is the default presenter for {GOVUKDesignSystemFormBuilder::Elements::ErrorSummary} and is
3
+ # intended to be easily replaceable should you have specific requirements that aren't met here.
4
+ #
5
+ # The basic behaviour is to always show the first error message. In Rails, error message order is
6
+ # determined by the order in which the validations run, but if you need to do any other transformation
7
+ # or concatenation, this is the place to do it.
8
+ class ErrorSummaryPresenter
9
+ # @param [Hash] error_messages the error message hash in a format that matches Rails'
10
+ # `object.errors.messages`, so the format should be:
11
+ #
12
+ # @example Input format:
13
+ # ErrorSummaryPresenter.new({ attribute_one: ["first error", "second error"], attribute_two: ["third error"] })
14
+ def initialize(error_messages)
15
+ @error_messages = error_messages
16
+ end
17
+
18
+ # Converts +@error_messages+ into an array of argument arrays that will be
19
+ # passed into {GOVUKDesignSystemFormBuilder::Elements::ErrorSummary#list_item}.
20
+ #
21
+ # @return [Array<Array(Symbol, String)>] array of attribute and message arrays
22
+ #
23
+ # @example Output format given the input above:
24
+ # [[:attribute_one, "first error"], [:attribute_two, "third error"]]
25
+ def formatted_error_messages
26
+ @error_messages.map { |attribute, messages| [attribute, messages.first] }
27
+ end
28
+ end
29
+ end
@@ -4,7 +4,7 @@ module GOVUKDesignSystemFormBuilder
4
4
  using PrefixableArray
5
5
 
6
6
  def html
7
- safe_join([item, @conditional])
7
+ safe_join([item, @conditional_content])
8
8
  end
9
9
 
10
10
  private
@@ -61,9 +61,9 @@ module GOVUKDesignSystemFormBuilder
61
61
  build_id('conditional')
62
62
  end
63
63
 
64
- def conditional_content(&block)
65
- if (conditional_block_content = block_given? && (capture { block.call }).presence)
66
- @conditional = conditional_container(conditional_block_content)
64
+ def conditional_content(block_content)
65
+ if block_content.present?
66
+ @conditional_content = conditional_container(block_content)
67
67
  @conditional_id = conditional_id
68
68
  end
69
69
  end
@@ -4,7 +4,7 @@ module GOVUKDesignSystemFormBuilder
4
4
  # Attributes eases working with default and custom attributes by:
5
5
  # * deeply merging them so both the default (required) attributes are
6
6
  # present
7
- # * joins the arrays into strings to maintain Rails 6.0.3 compatibility
7
+ # * joins the arrays into strings to maintain Rails 6.0.* compatibility
8
8
  class Attributes
9
9
  # Rather than attempt to combine these attributes, just overwrite the
10
10
  # form internally-generated values with those that are passed in. This
@@ -48,7 +48,7 @@ module GOVUKDesignSystemFormBuilder
48
48
  {
49
49
  id: field_id(link_errors: true),
50
50
  class: classes,
51
- aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
51
+ aria: { describedby: combine_references(hint_id, error_id, supplemental_id) }
52
52
  }
53
53
  end
54
54
 
@@ -4,7 +4,7 @@ module GOVUKDesignSystemFormBuilder
4
4
  private
5
5
 
6
6
  def classes
7
- [%(#{brand}-select), error_class].flatten.compact
7
+ combine_references(%(#{brand}-select), error_class)
8
8
  end
9
9
 
10
10
  def error_class
@@ -1,3 +1,3 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
- VERSION = '2.6.0'.freeze
2
+ VERSION = '2.7.3'.freeze
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require 'deep_merge/rails_compat'
2
2
  require 'active_support/configurable'
3
3
 
4
- [%w(refinements *.rb), %w(traits *.rb), %w(*.rb), %w(elements ** *.rb), %w(containers ** *.rb)]
4
+ [%w(presenters *.rb), %w(refinements *.rb), %w(traits *.rb), %w(*.rb), %w(elements ** *.rb), %w(containers ** *.rb)]
5
5
  .flat_map { |matcher| Dir.glob(File.join(__dir__, 'govuk_design_system_formbuilder', *matcher)) }
6
6
  .each { |file| require file }
7
7
 
@@ -27,20 +27,29 @@ module GOVUKDesignSystemFormBuilder
27
27
  # * +:default_submit_button_text+ sets the value assigned to +govuk_submit+,
28
28
  # defaults to 'Continue'.
29
29
  #
30
+ # * +:default_radio_divider_text+ sets the text automatically added to the
31
+ # radio button divider, defaults to 'or'
32
+ #
33
+ # * +:default_check_box_divider_text+ sets the text automatically added to the
34
+ # checkbox divider, defaults to 'or'
35
+ #
30
36
  # * +:default_submit_button_text+ sets the text used to divide the last radio
31
37
  # button in radio button fieldsets. As per the GOV.UK Design System spec,
32
38
  # it defaults to 'or'.
33
39
  #
34
- # * +:default_error_summary_title+ sets the text used in error summary
35
- # blocks. As per the GOV.UK Design System spec, it defaults to
36
- # 'There is a problem'.
37
- #
38
40
  # * +:default_collection_check_boxes_include_hidden+ controls whether or not
39
41
  # a hidden field is added when rendering a collection of check boxes
40
42
  #
41
43
  # * +:default_collection_radio_buttons_include_hidden+ controls whether or not
42
44
  # a hidden field is added when rendering a collection of radio buttons
43
45
  #
46
+ # * +:default_error_summary_title+ sets the text used in error summary
47
+ # blocks. As per the GOV.UK Design System spec, it defaults to
48
+ # 'There is a problem'.
49
+ #
50
+ # * +:default_error_summary_presenter+ the class that's instantiated when
51
+ # rendering an error summary and formats the messages for each attribute
52
+ #
44
53
  # * +:default_error_summary_error_order_method+ is the method that the library
45
54
  # will check for on the bound object to see whether or not to try ordering the
46
55
  # error messages
@@ -65,7 +74,9 @@ module GOVUKDesignSystemFormBuilder
65
74
  default_caption_size: 'm',
66
75
  default_submit_button_text: 'Continue',
67
76
  default_radio_divider_text: 'or',
77
+ default_check_box_divider_text: 'or',
68
78
  default_error_summary_title: 'There is a problem',
79
+ default_error_summary_presenter: Presenters::ErrorSummaryPresenter,
69
80
  default_error_summary_error_order_method: nil,
70
81
  default_collection_check_boxes_include_hidden: true,
71
82
  default_collection_radio_buttons_include_hidden: true,
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: 2.6.0
4
+ version: 2.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-14 00:00:00.000000000 Z
11
+ date: 2021-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep_merge
@@ -274,14 +274,14 @@ dependencies:
274
274
  requirements:
275
275
  - - "~>"
276
276
  - !ruby/object:Gem::Version
277
- version: 0.21.1
277
+ version: 0.22.0
278
278
  type: :development
279
279
  prerelease: false
280
280
  version_requirements: !ruby/object:Gem::Requirement
281
281
  requirements:
282
282
  - - "~>"
283
283
  - !ruby/object:Gem::Version
284
- version: 0.21.1
284
+ version: 0.22.0
285
285
  description: A Rails form builder that generates form inputs adhering to the GOV.UK
286
286
  Design System
287
287
  email:
@@ -331,6 +331,7 @@ files:
331
331
  - lib/govuk_design_system_formbuilder/elements/select.rb
332
332
  - lib/govuk_design_system_formbuilder/elements/submit.rb
333
333
  - lib/govuk_design_system_formbuilder/elements/text_area.rb
334
+ - lib/govuk_design_system_formbuilder/presenters/error_summary.rb
334
335
  - lib/govuk_design_system_formbuilder/proxy.rb
335
336
  - lib/govuk_design_system_formbuilder/refinements/prefixable_array.rb
336
337
  - lib/govuk_design_system_formbuilder/traits/caption.rb