govuk_design_system_formbuilder 2.6.0 → 2.7.3

Sign up to get free protection for your applications and to get access to all the features.
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