govuk_design_system_formbuilder 2.5.1 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98eb37a7c0dc6926abc94003671567e1d6d9ff64026d92dbd2bbeb62e132b5ac
4
- data.tar.gz: 3bdd6d81f7c94f28e39841088d056c8eb7615dab89cd750e589d516f71faae0a
3
+ metadata.gz: '08308443752eddad69642235b4098b788ed5c5eb701b6f97d344171b9654a135'
4
+ data.tar.gz: 0f3b209aee144ea52d46798b14a29ea1a85b9acf545413d0219efeff03b92e8e
5
5
  SHA512:
6
- metadata.gz: eae5b13528432a2c01a85aba212b74ecfcdb5740ecbe43bf6548749ebc1ab98b7a37281f7bea6b4e85964d73076e19a1a05326011d2edd71f1599075e6545e2b
7
- data.tar.gz: c24c784e74e4ae48fdafcca7bf3ba3b5e5f3e22a371f0b5e16bd6fc364f1cb3d386be4bff9ea03de0ce3d5857676eca58001b09284a625d9fcd2dc6ef728a9e5
6
+ metadata.gz: 425224ce7905d2dd33d2123698c6f35f68e2ac640743326f811ab7b45241134f640bc054b7b75a3813edd2be558b794119437d8d4917adbe03f5cc42e38a74b9
7
+ data.tar.gz: 22d147336200ed390422201ece082289db29d6ee637aad76157195c9401fbbe52cfe6c9c9a80cd357f41543d133009a248a207547b0debaae46503503d26fe93
data/README.md CHANGED
@@ -7,9 +7,9 @@
7
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
8
  [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=DFE-Digital/govuk_design_system_formbuilder)](https://dependabot.com)
9
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.11.0-brightgreen)](https://design-system.service.gov.uk)
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
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.6%20%E2%95%B1%206.1.3.1-E16D6D)](https://weblog.rubyonrails.org/releases/)
12
+ [![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
13
 
14
14
  This library provides an easy-to-use form builder for the [GOV.UK Design System](https://design-system.service.gov.uk/).
15
15
 
@@ -1,7 +1,7 @@
1
1
  require 'deep_merge/rails_compat'
2
2
  require 'active_support/configurable'
3
3
 
4
- [%w(traits *.rb), %w(*.rb), %w(elements ** *.rb), %w(containers ** *.rb)]
4
+ [%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
 
@@ -41,6 +41,10 @@ module GOVUKDesignSystemFormBuilder
41
41
  # * +:default_collection_radio_buttons_include_hidden+ controls whether or not
42
42
  # a hidden field is added when rendering a collection of radio buttons
43
43
  #
44
+ # * +:default_error_summary_error_order_method+ is the method that the library
45
+ # will check for on the bound object to see whether or not to try ordering the
46
+ # error messages
47
+ #
44
48
  # * +:localisation_schema_fallback+ sets the prefix elements for the array
45
49
  # used to build the localisation string. The final two elements are always
46
50
  # are the object name and attribute name. The _special_ value +__context__+,
@@ -62,6 +66,7 @@ module GOVUKDesignSystemFormBuilder
62
66
  default_submit_button_text: 'Continue',
63
67
  default_radio_divider_text: 'or',
64
68
  default_error_summary_title: 'There is a problem',
69
+ default_error_summary_error_order_method: nil,
65
70
  default_collection_check_boxes_include_hidden: true,
66
71
  default_collection_radio_buttons_include_hidden: true,
67
72
  default_submit_validate: false,
@@ -108,6 +113,8 @@ module GOVUKDesignSystemFormBuilder
108
113
  include GOVUKDesignSystemFormBuilder::Builder
109
114
  end
110
115
 
116
+ class FormBuilderProxy < FormBuilder; end
117
+
111
118
  # Disable Rails' div.field_with_error wrapper
112
119
  ActionView::Base.field_error_proc = ->(html_tag, _instance) { html_tag }
113
120
  end
@@ -1,12 +1,4 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
- module PrefixableArray
3
- refine Array do
4
- def prefix(text, delimiter: '-')
5
- map { |item| text + delimiter + item }
6
- end
7
- end
8
- end
9
-
10
2
  class Base
11
3
  delegate :content_tag, :safe_join, :tag, :link_to, :capture, to: :@builder
12
4
  delegate :config, to: GOVUKDesignSystemFormBuilder
@@ -23,21 +15,6 @@ module GOVUKDesignSystemFormBuilder
23
15
  html || ''
24
16
  end
25
17
 
26
- private
27
-
28
- # returns the attributes bound to the object that are
29
- # required to build all contained elements
30
- #
31
- # @return [GOVUKDesignSystemFormBuilder::FormBuilder, Symbol, Symbol] an array containing the
32
- # builder, object name and attribute name
33
- def bound
34
- [@builder, @object_name, @attribute_name]
35
- end
36
-
37
- def brand(override = nil)
38
- override || config.brand
39
- end
40
-
41
18
  # returns the id value used for the input
42
19
  #
43
20
  # @note field_id is overridden so that the error summary can link to the
@@ -59,6 +36,21 @@ module GOVUKDesignSystemFormBuilder
59
36
  end
60
37
  end
61
38
 
39
+ private
40
+
41
+ # returns the attributes bound to the object that are
42
+ # required to build all contained elements
43
+ #
44
+ # @return [GOVUKDesignSystemFormBuilder::FormBuilder, Symbol, Symbol] an array containing the
45
+ # builder, object name and attribute name
46
+ def bound
47
+ [@builder, @object_name, @attribute_name]
48
+ end
49
+
50
+ def brand(override = nil)
51
+ override || config.brand
52
+ end
53
+
62
54
  def has_errors?
63
55
  @builder.object.respond_to?(:errors) &&
64
56
  @builder.object.errors.any? &&
@@ -843,7 +843,7 @@ module GOVUKDesignSystemFormBuilder
843
843
 
844
844
  # Generates a submit button, green by default
845
845
  #
846
- # @param text [String] the button text
846
+ # @param text [String,Proc] the button text. When a +Proc+ is provided its contents will be rendered within the button element
847
847
  # @param warning [Boolean] makes the button red ({https://design-system.service.gov.uk/components/button/#warning-buttons warning}) when true
848
848
  # @param secondary [Boolean] makes the button grey ({https://design-system.service.gov.uk/components/button/#secondary-buttons secondary}) when true
849
849
  # @param classes [Array,String] Classes to add to the submit button
@@ -853,7 +853,7 @@ module GOVUKDesignSystemFormBuilder
853
853
  # client-side validation provided by the browser. This is to provide a more consistent and accessible user
854
854
  # experience
855
855
  # @param disabled [Boolean] makes the button disabled when true
856
- # @option kwargs [Hash] kwargs additional arguments are applied as attributes to the +input+ element
856
+ # @option kwargs [Hash] kwargs additional arguments are applied as attributes to the +button+ element
857
857
  # @param block [Block] When content is passed in via a block the submit element and the block content will
858
858
  # be wrapped in a +<div class="govuk-button-group">+ which will space the buttons and links within
859
859
  # evenly.
@@ -861,8 +861,9 @@ module GOVUKDesignSystemFormBuilder
861
861
  # @return [ActiveSupport::SafeBuffer] HTML output
862
862
  # @note Only the first additional button or link (passed in via a block) will be given the
863
863
  # 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
864
+ # @note This helper always renders an +<button type='submit'>+ tag. Previous versions of this gem rendered
865
+ # a +`<input type='submit'>' tag instead, but there is a {https://github.com/alphagov/govuk_elements/issues/545 longstanding bug}
866
+ # with this approach where the top few pixels don't initiate a submission when clicked.
866
867
  # @see https://design-system.service.gov.uk/components/button/#stop-users-from-accidentally-sending-information-more-than-once
867
868
  # GOV.UK double click prevention
868
869
  #
@@ -930,7 +931,11 @@ module GOVUKDesignSystemFormBuilder
930
931
  # @param title [String] the error summary heading
931
932
  # @param link_base_errors_to [Symbol,String] set the field that errors on +:base+ are linked
932
933
  # to, as there won't be a field representing the object base.
934
+ # @param order [Array<Symbol>] the attribute order in which error messages are displayed. Ordered
935
+ # attributes will appear first and unordered ones will be last, sorted in the default manner (in
936
+ # which they were defined on the model).
933
937
  # @option kwargs [Hash] kwargs additional arguments are applied as attributes to the error summary +div+ element
938
+ # @param block [Block] arbitrary HTML that will be rendered between title and error message list
934
939
  #
935
940
  # @note Only the first error in the +#errors+ array for each attribute will
936
941
  # be included.
@@ -939,8 +944,8 @@ module GOVUKDesignSystemFormBuilder
939
944
  # = f.govuk_error_summary 'Uh-oh, spaghettios'
940
945
  #
941
946
  # @see https://design-system.service.gov.uk/components/error-summary/ GOV.UK error summary
942
- def govuk_error_summary(title = config.default_error_summary_title, link_base_errors_to: nil, **kwargs)
943
- Elements::ErrorSummary.new(self, object_name, title, link_base_errors_to: link_base_errors_to, **kwargs).html
947
+ def govuk_error_summary(title = config.default_error_summary_title, link_base_errors_to: nil, order: nil, **kwargs, &block)
948
+ Elements::ErrorSummary.new(self, object_name, title, link_base_errors_to: link_base_errors_to, order: order, **kwargs, &block).html
944
949
  end
945
950
 
946
951
  # Generates a fieldset containing the contents of the block
@@ -0,0 +1,65 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ # NOTE: this is currently considered experimental, it's likely to change based on feedback.
3
+ #
4
+ # BuilderHelper contains methods that expose the form builder's functionality
5
+ # externally. The objectives are to allow:
6
+ #
7
+ # * rendering the error summary outside of the form
8
+ #
9
+ # * setting the id of custom form elements (rich text editors, date pickers,
10
+ # sliders, etc) using the formbuilder's internal logic, allowing them to be
11
+ # linked from the error summary
12
+ module BuilderHelper
13
+ # Returns the form builder generated id for an object's attribute, allowing
14
+ # users to force their custom element ids to match those that'll be generated
15
+ # by the error summary.
16
+ # @param object [ActiveRecord::Base,ActiveModel::Model,Object] the object that we want to
17
+ # generate an id for
18
+ # @param object_name [Symbol] the object's name, the singular version of the object's class
19
+ # name, e.g., +Person+ is +:person+.
20
+ # @param attribute_name [Symbol] the attribute we're generating an id for
21
+ # @param value [Object] the value of the attribute. Only necessary for fields with
22
+ # multiple form elements like radio buttons and checkboxes
23
+ # @param link_errors [Boolean] toggles whether or not to override the field id with the
24
+ # error id when there are errors on the +object+. Only relevant for radio buttons
25
+ # and check boxes.
26
+ def govuk_field_id(object, attribute_name, object_name = nil, value: nil, link_errors: true)
27
+ (object_name = retrieve_object_name(object)) if object_name.nil?
28
+
29
+ proxy_base(object, object_name, attribute_name, value: value).field_id(link_errors: link_errors)
30
+ end
31
+
32
+ # Renders an error summary
33
+ # @param object [ActiveRecord::Base,ActiveModel::Model,Object] the object we'll be rendering
34
+ # the errors for
35
+ # @param object_name [Symbol] the object's name, the singular version of the object's class
36
+ # name, e.g., +Person+ is +:person+. If none is supplied we'll try to infer it from
37
+ # the object, so it'll probably be necessary for regular Ruby objects
38
+ # @option args [Array] options passed through to the builder's +#govuk_error_summary+
39
+ # @option kwargs [Hash] keyword options passed through to the builder's +#govuk_error_summary+
40
+ #
41
+ # @example
42
+ # = govuk_error_summary(@registration)
43
+ #
44
+ # @see https://design-system.service.gov.uk/components/error-summary/ GOV.UK error summary
45
+ def govuk_error_summary(object, object_name = nil, *args, **kwargs, &block)
46
+ (object_name = retrieve_object_name(object)) if object_name.nil?
47
+
48
+ proxy_builder(object, object_name, self, {}).govuk_error_summary(*args, **kwargs, &block)
49
+ end
50
+
51
+ private
52
+
53
+ def proxy_base(object, object_name, attribute_name, value: nil)
54
+ GOVUKDesignSystemFormBuilder::Proxy.new(object, object_name, attribute_name, value: value)
55
+ end
56
+
57
+ def proxy_builder(object, object_name, template, options)
58
+ GOVUKDesignSystemFormBuilder::FormBuilderProxy.new(object_name, object, template, options)
59
+ end
60
+
61
+ def retrieve_object_name(object)
62
+ object.to_model.model_name.singular
63
+ end
64
+ end
65
+ end
@@ -2,13 +2,10 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module CheckBoxes
4
4
  class FieldsetCheckBox < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Label
8
6
  include Traits::Hint
9
- include Traits::FieldsetItem
10
- include Traits::Conditional
11
7
  include Traits::HTMLAttributes
8
+ include Traits::FieldsetItem
12
9
 
13
10
  def initialize(builder, object_name, attribute_name, value, unchecked_value, label:, hint:, link_errors:, multiple:, **kwargs, &block)
14
11
  super(builder, object_name, attribute_name)
@@ -21,49 +18,22 @@ module GOVUKDesignSystemFormBuilder
21
18
  @link_errors = link_errors
22
19
  @html_attributes = kwargs
23
20
 
24
- if block_given?
25
- @conditional_content = wrap_conditional(block)
26
- @conditional_id = conditional_id
27
- end
28
- end
29
-
30
- def html
31
- safe_join([item, @conditional_content])
21
+ conditional_content(&block)
32
22
  end
33
23
 
34
24
  private
35
25
 
36
- def item
37
- tag.div(class: %(#{brand}-checkboxes__item)) do
38
- safe_join([check_box, label_element, hint_element])
39
- end
26
+ def input_type
27
+ :checkboxes
40
28
  end
41
29
 
42
- def check_box
30
+ def input
43
31
  @builder.check_box(@attribute_name, attributes(@html_attributes), @value, @unchecked_value)
44
32
  end
45
33
 
46
- def options
47
- {
48
- id: field_id(link_errors: @link_errors),
49
- class: classes,
50
- multiple: @multiple,
51
- aria: { describedby: [hint_id] },
52
- data: { 'aria-controls' => @conditional_id }
53
- }
54
- end
55
-
56
- def classes
57
- %w(checkboxes__input).prefix(brand)
58
- end
59
-
60
34
  def fieldset_options
61
35
  { checkbox: true }
62
36
  end
63
-
64
- def conditional_classes
65
- %w(checkboxes__conditional checkboxes__conditional--hidden).prefix(brand)
66
- end
67
37
  end
68
38
  end
69
39
  end
@@ -4,12 +4,13 @@ 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:, **kwargs)
8
- super(builder, object_name, nil)
7
+ def initialize(builder, object_name, title, link_base_errors_to:, order:, **kwargs, &block)
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
+ @order = order
13
14
  end
14
15
 
15
16
  def html
@@ -27,17 +28,45 @@ module GOVUKDesignSystemFormBuilder
27
28
  end
28
29
 
29
30
  def summary
30
- tag.div(class: summary_class('body')) do
31
- tag.ul(class: [%(#{brand}-list), summary_class('list')]) do
32
- safe_join(list)
33
- end
34
- end
31
+ tag.div(class: summary_class('body')) { safe_join([@block_content, list]) }
35
32
  end
36
33
 
37
34
  def list
38
- @builder.object.errors.messages.map do |attribute, messages|
39
- list_item(attribute, messages.first)
35
+ tag.ul(class: [%(#{brand}-list), summary_class('list')]) do
36
+ safe_join(error_messages.map { |attribute, messages| list_item(attribute, messages.first) })
37
+ end
38
+ end
39
+
40
+ def error_messages
41
+ messages = @builder.object.errors.messages
42
+
43
+ if reorder_errors?
44
+ adjustment = error_order.size + messages.size
45
+
46
+ return messages.sort_by.with_index do |(attr, _val), i|
47
+ error_order.index(attr) || (i + adjustment)
48
+ end
40
49
  end
50
+
51
+ @builder.object.errors.messages
52
+ end
53
+
54
+ def reorder_errors?
55
+ object = @builder.object
56
+
57
+ @order || (error_order_method &&
58
+ object.respond_to?(error_order_method) &&
59
+ object.send(error_order_method).present?)
60
+ end
61
+
62
+ def error_order
63
+ @order || @builder.object.send(config.default_error_summary_error_order_method)
64
+ end
65
+
66
+ # this method will be called on the bound object to see if custom error ordering
67
+ # has been enabled
68
+ def error_order_method
69
+ config.default_error_summary_error_order_method
41
70
  end
42
71
 
43
72
  def list_item(attribute, message)
@@ -2,13 +2,10 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Radios
4
4
  class FieldsetRadioButton < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Label
8
6
  include Traits::Hint
9
- include Traits::FieldsetItem
10
- include Traits::Conditional
11
7
  include Traits::HTMLAttributes
8
+ include Traits::FieldsetItem
12
9
 
13
10
  def initialize(builder, object_name, attribute_name, value, label:, hint:, link_errors:, **kwargs, &block)
14
11
  super(builder, object_name, attribute_name)
@@ -19,43 +16,21 @@ module GOVUKDesignSystemFormBuilder
19
16
  @link_errors = has_errors? && link_errors
20
17
  @html_attributes = kwargs
21
18
 
22
- if block_given?
23
- @conditional_content = wrap_conditional(block)
24
- @conditional_id = conditional_id
25
- end
26
- end
27
-
28
- def html
29
- safe_join([radio, @conditional_content])
19
+ conditional_content(&block)
30
20
  end
31
21
 
32
22
  private
33
23
 
34
- def radio
35
- tag.div(class: %(#{brand}-radios__item)) do
36
- safe_join([input, label_element, hint_element])
37
- end
38
- end
39
-
40
- def fieldset_options
41
- { radio: true }
24
+ def input_type
25
+ :radios
42
26
  end
43
27
 
44
28
  def input
45
29
  @builder.radio_button(@attribute_name, @value, **attributes(@html_attributes))
46
30
  end
47
31
 
48
- def options
49
- {
50
- id: field_id(link_errors: @link_errors),
51
- aria: { describedby: [hint_id] },
52
- data: { 'aria-controls' => @conditional_id },
53
- class: %w(radios__input).prefix(brand)
54
- }
55
- end
56
-
57
- def conditional_classes
58
- %w(radios__conditional radios__conditional--hidden).prefix(brand)
32
+ def fieldset_options
33
+ { radio: true }
59
34
  end
60
35
  end
61
36
  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,
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+
3
+ module GOVUKDesignSystemFormBuilder
4
+ class Proxy < GOVUKDesignSystemFormBuilder::Base
5
+ NullBuilder = Struct.new(:object)
6
+
7
+ def initialize(object, object_name, attribute_name, value: nil)
8
+ super(NullBuilder.new(object), object_name, attribute_name)
9
+
10
+ @value = value
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module PrefixableArray
3
+ refine Array do
4
+ def prefix(text, delimiter: '-')
5
+ map { |item| [text, item].join(delimiter.to_s) }
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,8 +1,38 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Traits
3
3
  module FieldsetItem
4
+ using PrefixableArray
5
+
6
+ def html
7
+ safe_join([item, @conditional])
8
+ end
9
+
4
10
  private
5
11
 
12
+ def class_prefix
13
+ %(#{brand}-#{input_type})
14
+ end
15
+
16
+ def item
17
+ tag.div(class: %(#{class_prefix}__item)) do
18
+ safe_join([input, label_element, hint_element])
19
+ end
20
+ end
21
+
22
+ def options
23
+ {
24
+ id: field_id(link_errors: @link_errors),
25
+ class: classes,
26
+ multiple: @multiple,
27
+ aria: { describedby: [hint_id] },
28
+ data: { 'aria-controls' => @conditional_id }
29
+ }
30
+ end
31
+
32
+ def classes
33
+ [%(#{class_prefix}__input)]
34
+ end
35
+
6
36
  def label_element
7
37
  @label_element ||= if @label.nil?
8
38
  Elements::Null.new
@@ -26,6 +56,27 @@ module GOVUKDesignSystemFormBuilder
26
56
  def hint_options
27
57
  { value: @value }.merge(fieldset_options)
28
58
  end
59
+
60
+ def conditional_id
61
+ build_id('conditional')
62
+ end
63
+
64
+ def conditional_content(&block)
65
+ if (conditional_block_content = block_given? && (capture { block.call }).presence)
66
+ @conditional = conditional_container(conditional_block_content)
67
+ @conditional_id = conditional_id
68
+ end
69
+ end
70
+
71
+ def conditional_container(content)
72
+ tag.div(class: conditional_classes, id: conditional_id) do
73
+ content
74
+ end
75
+ end
76
+
77
+ def conditional_classes
78
+ %w(__conditional __conditional--hidden).prefix(class_prefix, delimiter: nil)
79
+ end
29
80
  end
30
81
  end
31
82
  end
@@ -6,16 +6,11 @@ module GOVUKDesignSystemFormBuilder
6
6
  # present
7
7
  # * joins the arrays into strings to maintain Rails 6.0.3 compatibility
8
8
  class Attributes
9
- # Don't try to deep merge these fields, when we remove duplicates
10
- # whilst merging the resulting values later, repeating words are lost
11
- SKIP = [
12
- %i(id),
13
- %i(value),
14
- %i(title),
15
- %i(alt),
16
- %i(href),
17
- %i(aria label)
18
- ].freeze
9
+ # Rather than attempt to combine these attributes, just overwrite the
10
+ # form internally-generated values with those that are passed in. This
11
+ # prevents the merge/unique value logic from affecting the content
12
+ # (i.e. by remvoving duplicated words).
13
+ UNMERGEABLE = [%i(id), %i(value), %i(title), %i(alt), %i(href), %i(aria label)].freeze
19
14
 
20
15
  def initialize(defaults, custom)
21
16
  @merged = defaults.deeper_merge(deep_split_values(custom))
@@ -33,19 +28,17 @@ module GOVUKDesignSystemFormBuilder
33
28
  when Hash
34
29
  deep_split_values(value, key)
35
30
  when String
36
- split_list_values(key, value, parent)
31
+ split_mergeable(key, value, parent)
37
32
  else
38
33
  value
39
34
  end
40
35
  end
41
36
  end
42
37
 
43
- def split_list_values(key, value, parent = nil)
44
- if [parent, key].compact.in?(SKIP)
45
- value
46
- else
47
- value.split
48
- end
38
+ def split_mergeable(key, value, parent = nil)
39
+ return value if [parent, key].compact.in?(UNMERGEABLE)
40
+
41
+ value.split
49
42
  end
50
43
 
51
44
  def deep_join_values(hash)
@@ -1,3 +1,3 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
- VERSION = '2.5.1'.freeze
2
+ VERSION = '2.7.0'.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: 2.5.1
4
+ version: 2.7.0
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-05-13 00:00:00.000000000 Z
11
+ date: 2021-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep_merge
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: rubocop-govuk
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '='
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 4.0.0.pre.1
75
+ version: 4.0.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '='
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 4.0.0.pre.1
82
+ version: 4.0.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pry
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -274,14 +274,14 @@ dependencies:
274
274
  requirements:
275
275
  - - "~>"
276
276
  - !ruby/object:Gem::Version
277
- version: 0.20.2
277
+ version: 0.21.1
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.20.2
284
+ version: 0.21.1
285
285
  description: A Rails form builder that generates form inputs adhering to the GOV.UK
286
286
  Design System
287
287
  email:
@@ -295,6 +295,7 @@ files:
295
295
  - lib/govuk_design_system_formbuilder.rb
296
296
  - lib/govuk_design_system_formbuilder/base.rb
297
297
  - lib/govuk_design_system_formbuilder/builder.rb
298
+ - lib/govuk_design_system_formbuilder/builder_helper.rb
298
299
  - lib/govuk_design_system_formbuilder/containers/button_group.rb
299
300
  - lib/govuk_design_system_formbuilder/containers/character_count.rb
300
301
  - lib/govuk_design_system_formbuilder/containers/check_boxes.rb
@@ -330,9 +331,10 @@ files:
330
331
  - lib/govuk_design_system_formbuilder/elements/select.rb
331
332
  - lib/govuk_design_system_formbuilder/elements/submit.rb
332
333
  - lib/govuk_design_system_formbuilder/elements/text_area.rb
334
+ - lib/govuk_design_system_formbuilder/proxy.rb
335
+ - lib/govuk_design_system_formbuilder/refinements/prefixable_array.rb
333
336
  - lib/govuk_design_system_formbuilder/traits/caption.rb
334
337
  - lib/govuk_design_system_formbuilder/traits/collection_item.rb
335
- - lib/govuk_design_system_formbuilder/traits/conditional.rb
336
338
  - lib/govuk_design_system_formbuilder/traits/error.rb
337
339
  - lib/govuk_design_system_formbuilder/traits/fieldset_item.rb
338
340
  - lib/govuk_design_system_formbuilder/traits/hint.rb
@@ -1,17 +0,0 @@
1
- module GOVUKDesignSystemFormBuilder
2
- module Traits
3
- module Conditional
4
- private
5
-
6
- def conditional_id
7
- build_id('conditional')
8
- end
9
-
10
- def wrap_conditional(block)
11
- tag.div(class: conditional_classes, id: conditional_id) do
12
- capture { block.call }
13
- end
14
- end
15
- end
16
- end
17
- end