govuk_design_system_formbuilder 2.5.1b1 → 2.6.0
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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/govuk_design_system_formbuilder.rb +9 -3
- data/lib/govuk_design_system_formbuilder/base.rb +15 -23
- data/lib/govuk_design_system_formbuilder/builder.rb +6 -2
- data/lib/govuk_design_system_formbuilder/builder_helper.rb +65 -0
- data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +5 -35
- data/lib/govuk_design_system_formbuilder/elements/date.rb +0 -4
- data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +36 -9
- data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +6 -31
- data/lib/govuk_design_system_formbuilder/proxy.rb +13 -0
- data/lib/govuk_design_system_formbuilder/refinements/prefixable_array.rb +9 -0
- data/lib/govuk_design_system_formbuilder/traits/fieldset_item.rb +51 -0
- data/lib/govuk_design_system_formbuilder/traits/html_attributes.rb +16 -4
- data/lib/govuk_design_system_formbuilder/version.rb +1 -1
- metadata +13 -11
- data/lib/govuk_design_system_formbuilder/traits/conditional.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd0f0c49f266a8cb411ebed4833b6284cc8cc4b6acd8ce3bf87d705feb40062b
|
4
|
+
data.tar.gz: b2659204e304dd40ed2254d06f43acdd4b5b5f13fc48d180741645d004c15719
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 962d77c5cc9b3501f0b8efab08a9f7c930d3aed9b28e96e06bd4e9851fd00586eb557a43150f6b911c7ad5044d0cc4e0bc08027697faf223aa70ce0765558898
|
7
|
+
data.tar.gz: 8af398e7d5673dd8b8b5f25810d88afb281a297f409c5883d567fd13a9f0347cbe644c2f32f6e69b1ec8a0e261ad81abf723e444d6186bdfb7f9901431f70c10
|
data/README.md
CHANGED
@@ -7,9 +7,9 @@
|
|
7
7
|
[](https://codeclimate.com/github/DFE-Digital/govuk_design_system_formbuilder/test_coverage)
|
8
8
|
[](https://dependabot.com)
|
9
9
|
[](https://github.com/DFE-Digital/govuk_design_system_formbuilder/blob/master/LICENSE)
|
10
|
-
[](https://design-system.service.gov.uk)
|
11
11
|
[](https://www.ruby-lang.org/en/downloads/)
|
12
|
-
[](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,
|
@@ -72,8 +77,7 @@ module GOVUKDesignSystemFormBuilder
|
|
72
77
|
localisation_schema_legend: nil,
|
73
78
|
localisation_schema_caption: nil,
|
74
79
|
|
75
|
-
enable_logger: true
|
76
|
-
enable_log_on_invalid_date: false
|
80
|
+
enable_logger: true
|
77
81
|
}.freeze
|
78
82
|
|
79
83
|
DEFAULTS.each_key { |k| config_accessor(k) { DEFAULTS[k] } }
|
@@ -109,6 +113,8 @@ module GOVUKDesignSystemFormBuilder
|
|
109
113
|
include GOVUKDesignSystemFormBuilder::Builder
|
110
114
|
end
|
111
115
|
|
116
|
+
class FormBuilderProxy < FormBuilder; end
|
117
|
+
|
112
118
|
# Disable Rails' div.field_with_error wrapper
|
113
119
|
ActionView::Base.field_error_proc = ->(html_tag, _instance) { html_tag }
|
114
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? &&
|
@@ -930,7 +930,11 @@ module GOVUKDesignSystemFormBuilder
|
|
930
930
|
# @param title [String] the error summary heading
|
931
931
|
# @param link_base_errors_to [Symbol,String] set the field that errors on +:base+ are linked
|
932
932
|
# to, as there won't be a field representing the object base.
|
933
|
+
# @param order [Array<Symbol>] the attribute order in which error messages are displayed. Ordered
|
934
|
+
# attributes will appear first and unordered ones will be last, sorted in the default manner (in
|
935
|
+
# which they were defined on the model).
|
933
936
|
# @option kwargs [Hash] kwargs additional arguments are applied as attributes to the error summary +div+ element
|
937
|
+
# @param block [Block] arbitrary HTML that will be rendered between title and error message list
|
934
938
|
#
|
935
939
|
# @note Only the first error in the +#errors+ array for each attribute will
|
936
940
|
# be included.
|
@@ -939,8 +943,8 @@ module GOVUKDesignSystemFormBuilder
|
|
939
943
|
# = f.govuk_error_summary 'Uh-oh, spaghettios'
|
940
944
|
#
|
941
945
|
# @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
|
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
|
944
948
|
end
|
945
949
|
|
946
950
|
# 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
|
-
|
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
|
37
|
-
|
38
|
-
safe_join([check_box, label_element, hint_element])
|
39
|
-
end
|
26
|
+
def input_type
|
27
|
+
:checkboxes
|
40
28
|
end
|
41
29
|
|
42
|
-
def
|
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
|
@@ -82,10 +82,6 @@ module GOVUKDesignSystemFormBuilder
|
|
82
82
|
|
83
83
|
nil
|
84
84
|
end
|
85
|
-
elsif config.enable_log_on_invalid_date
|
86
|
-
warn("invalid Date-like object: should be a Date, Time, DateTime or Hash in MULTIPARAMETER_KEY format")
|
87
|
-
|
88
|
-
nil
|
89
85
|
else
|
90
86
|
fail(ArgumentError, "invalid Date-like object: must be a Date, Time, DateTime or Hash in MULTIPARAMETER_KEY format")
|
91
87
|
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,43 @@ module GOVUKDesignSystemFormBuilder
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def summary
|
30
|
-
tag.div(class: summary_class('body'))
|
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
|
-
|
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
|
+
return messages.sort_by.with_index(1) do |(attr, _val), i|
|
45
|
+
error_order.index(attr) || (i + messages.size)
|
46
|
+
end
|
40
47
|
end
|
48
|
+
|
49
|
+
@builder.object.errors.messages
|
50
|
+
end
|
51
|
+
|
52
|
+
def reorder_errors?
|
53
|
+
object = @builder.object
|
54
|
+
|
55
|
+
@order || (error_order_method &&
|
56
|
+
object.respond_to?(error_order_method) &&
|
57
|
+
object.send(error_order_method).present?)
|
58
|
+
end
|
59
|
+
|
60
|
+
def error_order
|
61
|
+
@order || @builder.object.send(config.default_error_summary_error_order_method)
|
62
|
+
end
|
63
|
+
|
64
|
+
# this method will be called on the bound object to see if custom error ordering
|
65
|
+
# has been enabled
|
66
|
+
def error_order_method
|
67
|
+
config.default_error_summary_error_order_method
|
41
68
|
end
|
42
69
|
|
43
70
|
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
|
-
|
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
|
35
|
-
|
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
|
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
|
@@ -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
|
@@ -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
|
@@ -1,11 +1,17 @@
|
|
1
1
|
module GOVUKDesignSystemFormBuilder
|
2
2
|
module Traits
|
3
3
|
module HTMLAttributes
|
4
|
-
# Attributes eases working with default and custom attributes by
|
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
7
|
# * joins the arrays into strings to maintain Rails 6.0.3 compatibility
|
8
8
|
class Attributes
|
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
|
14
|
+
|
9
15
|
def initialize(defaults, custom)
|
10
16
|
@merged = defaults.deeper_merge(deep_split_values(custom))
|
11
17
|
end
|
@@ -16,19 +22,25 @@ module GOVUKDesignSystemFormBuilder
|
|
16
22
|
|
17
23
|
private
|
18
24
|
|
19
|
-
def deep_split_values(hash)
|
25
|
+
def deep_split_values(hash, parent = nil)
|
20
26
|
hash.each.with_object({}) do |(key, value), result|
|
21
27
|
result[key] = case value
|
22
28
|
when Hash
|
23
|
-
deep_split_values(value)
|
29
|
+
deep_split_values(value, key)
|
24
30
|
when String
|
25
|
-
value
|
31
|
+
split_mergeable(key, value, parent)
|
26
32
|
else
|
27
33
|
value
|
28
34
|
end
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
38
|
+
def split_mergeable(key, value, parent = nil)
|
39
|
+
return value if [parent, key].compact.in?(UNMERGEABLE)
|
40
|
+
|
41
|
+
value.split
|
42
|
+
end
|
43
|
+
|
32
44
|
def deep_join_values(hash)
|
33
45
|
hash.each.with_object({}) do |(key, value), result|
|
34
46
|
result[key] = case value
|
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.
|
4
|
+
version: 2.6.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-
|
11
|
+
date: 2021-06-14 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
|
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
|
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.
|
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.
|
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
|
@@ -363,9 +365,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
363
365
|
version: '0'
|
364
366
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
365
367
|
requirements:
|
366
|
-
- - "
|
368
|
+
- - ">="
|
367
369
|
- !ruby/object:Gem::Version
|
368
|
-
version:
|
370
|
+
version: '0'
|
369
371
|
requirements: []
|
370
372
|
rubygems_version: 3.1.6
|
371
373
|
signing_key:
|
@@ -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
|