govuk_design_system_formbuilder 2.4.0 → 2.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56faf8610c088256377104bf569648d400a885f14ac4473004f6e274e369bcf0
4
- data.tar.gz: d33bc39a755f8241b61dc94bef11b51734786e781a0f2e046b27438996161aa2
3
+ metadata.gz: bad17ea5b7fd24f59da43ac8e0348d27c07589bce648172278c7041e95c4a702
4
+ data.tar.gz: e8dee08e15dfe0dc4a34de248ef8a2991e789a74ea3452324bbcad81e0ec6612
5
5
  SHA512:
6
- metadata.gz: cb539b28abcd66fedd8bfb67ae7341e3394503eea648c5fd7c88a453163cac93b31ff5c21d91971f36348bb2f194becc5346382f995d464c148865a6c17ab57c
7
- data.tar.gz: 4dc4ad392b0889678d009e4b0c4e502c8dad962b9a6ded83b079e319efd0e7760c78151bfe964d3d825328eef9760324a124ea7800593f2be0e454f5836722d5
6
+ metadata.gz: ea8519f8c72d431fa56feae8d98e21ff90117c58dcd1e91385ed41a4863299cd74b15f959dd4e4118e3281bccd8a048625013dcdc2dd00fa1d873479d5294f57
7
+ data.tar.gz: 969f85302cc4c1e898664c04bf1d435d69ed0408fa0bf03890160803c0b6574eabeafc16418cfe8df353e718ff062f6600272d6bccbd596be4fe248c5295dfc5
data/README.md CHANGED
@@ -8,8 +8,8 @@
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
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)
11
- [![Rails](https://img.shields.io/badge/Ruby-2.6.6%20%E2%95%B1%202.7.2%20%E2%95%B1%203.0.0-E16D6D)](https://www.ruby-lang.org/en/downloads/)
12
- [![Ruby](https://img.shields.io/badge/Rails-6.0.3%20%E2%95%B1%206.1.0-E16D6D)](https://weblog.rubyonrails.org/releases/)
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/)
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
 
@@ -49,6 +49,9 @@ module GOVUKDesignSystemFormBuilder
49
49
  # * +:localisation_schema_legend+, +:localisation_schema_hint+ and
50
50
  # +:localisation_schema_label+ each override the schema root for their
51
51
  # particular context, allowing them to be independently customised.
52
+ #
53
+ # * +:enable_logger+ controls whether or not the library will emit log
54
+ # messages via Rails.logger.warn, defaults to +true+
52
55
  # ===
53
56
  DEFAULTS = {
54
57
  brand: 'govuk',
@@ -67,7 +70,9 @@ module GOVUKDesignSystemFormBuilder
67
70
  localisation_schema_label: nil,
68
71
  localisation_schema_hint: nil,
69
72
  localisation_schema_legend: nil,
70
- localisation_schema_caption: nil
73
+ localisation_schema_caption: nil,
74
+
75
+ enable_logger: true
71
76
  }.freeze
72
77
 
73
78
  DEFAULTS.each_key { |k| config_accessor(k) { DEFAULTS[k] } }
@@ -66,7 +66,7 @@ module GOVUKDesignSystemFormBuilder
66
66
  end
67
67
 
68
68
  def described_by(*ids)
69
- ids.flatten.compact.join(' ').presence
69
+ ids.flatten.compact
70
70
  end
71
71
 
72
72
  # Builds the values used for HTML id attributes throughout the builder
@@ -96,5 +96,11 @@ module GOVUKDesignSystemFormBuilder
96
96
  .parameterize
97
97
  .tr(replace, delimiter)
98
98
  end
99
+
100
+ def warn(message)
101
+ return unless config.enable_logger
102
+
103
+ Rails.logger.warn(message)
104
+ end
99
105
  end
100
106
  end
@@ -381,6 +381,7 @@ module GOVUKDesignSystemFormBuilder
381
381
  # supplied the hint will be wrapped in a +div+ instead of a +span+
382
382
  # @option hint text [String] the hint text
383
383
  # @option hint kwargs [Hash] additional arguments are applied as attributes to the hint
384
+ # @param label [Hash,Proc] configures or sets the associated label content
384
385
  # @option label text [String] the label text
385
386
  # @option label size [String] the size of the label font, can be +xl+, +l+, +m+, +s+ or nil
386
387
  # @option label tag [Symbol,String] the label's wrapper tag, intended to allow labels to act as page headings
@@ -412,7 +413,7 @@ module GOVUKDesignSystemFormBuilder
412
413
  # label: -> { tag.h3("Which team did you represent?") }
413
414
  #
414
415
  def govuk_collection_select(attribute_name, collection, value_method, text_method, options: {}, hint: {}, label: {}, caption: {}, form_group: {}, **kwargs, &block)
415
- Elements::Select.new(
416
+ Elements::CollectionSelect.new(
416
417
  self,
417
418
  object_name,
418
419
  attribute_name,
@@ -429,6 +430,42 @@ module GOVUKDesignSystemFormBuilder
429
430
  ).html
430
431
  end
431
432
 
433
+ # Generates a +select+ element containing an +option+ for every choice provided
434
+ #
435
+ # @param attribute_name [Symbol] The name of the attribute
436
+ # @param choices [Array,Hash] The +option+ values, usually provided via
437
+ # the +options_for_select+ or +grouped_options_for_select+ helpers.
438
+ # @param options [Hash] Options hash passed through to Rails' +select+ helper
439
+ # @param hint [Hash,Proc] The content of the hint. No hint will be added if 'text' is left +nil+. When a +Proc+ is
440
+ # supplied the hint will be wrapped in a +div+ instead of a +span+
441
+ # @option hint text [String] the hint text
442
+ # @option hint kwargs [Hash] additional arguments are applied as attributes to the hint
443
+ # @param label [Hash,Proc] configures or sets the associated label content
444
+ # @option label text [String] the label text
445
+ # @option label size [String] the size of the label font, can be +xl+, +l+, +m+, +s+ or nil
446
+ # @option label tag [Symbol,String] the label's wrapper tag, intended to allow labels to act as page headings
447
+ # @option label hidden [Boolean] control the visability of the label. Hidden labels will stil be read by screenreaders
448
+ # @option label kwargs [Hash] additional arguments are applied as attributes on the +label+ element
449
+ # @param form_group [Hash] configures the form group
450
+ # @option form_group classes [Array,String] sets the form group's classes
451
+ # @option form_group kwargs [Hash] additional attributes added to the form group
452
+ # @param block [Block] build the contents of the select element manually for exact control
453
+ # @see https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select Rails select (called by govuk_collection_select)
454
+ # @return [ActiveSupport::SafeBuffer] HTML output
455
+ #
456
+ # @example A select box with custom data attributes
457
+ #
458
+ # @colours = [
459
+ # ["PapayaWhip", "pw", { data: { hex: "#ffefd5" } }],
460
+ # ["Chocolate", "choc", { data: { hex: "#d2691e" } }],
461
+ # ]
462
+ #
463
+ # = f.govuk_select :hat_colour, options_for_select(@colours)
464
+ #
465
+ def govuk_select(attribute_name, choices = nil, options: {}, label: {}, hint: {}, form_group: {}, caption: {}, **kwargs, &block)
466
+ Elements::Select.new(self, object_name, attribute_name, choices, options: options, label: label, hint: hint, form_group: form_group, caption: caption, **kwargs, &block).html
467
+ end
468
+
432
469
  # Generates a radio button for each item in the supplied collection
433
470
  #
434
471
  # @note Unlike the Rails +#collection_radio_buttons+ helper, this version can also insert
@@ -24,7 +24,7 @@ module GOVUKDesignSystemFormBuilder
24
24
  def options
25
25
  {
26
26
  class: classes,
27
- aria: { describedby: @described_by }
27
+ aria: { describedby: [@described_by] }
28
28
  }
29
29
  end
30
30
 
@@ -48,7 +48,7 @@ module GOVUKDesignSystemFormBuilder
48
48
  id: field_id(link_errors: @link_errors),
49
49
  class: classes,
50
50
  multiple: @multiple,
51
- aria: { describedby: hint_id },
51
+ aria: { describedby: [hint_id] },
52
52
  data: { 'aria-controls' => @conditional_id }
53
53
  }
54
54
  end
@@ -0,0 +1,52 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ class CollectionSelect < Base
4
+ include Traits::Error
5
+ include Traits::Label
6
+ include Traits::Hint
7
+ include Traits::Supplemental
8
+ include Traits::HTMLAttributes
9
+ include Traits::Select
10
+
11
+ def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, hint:, label:, caption:, form_group:, options: {}, **kwargs, &block)
12
+ super(builder, object_name, attribute_name, &block)
13
+
14
+ @collection = collection
15
+ @value_method = value_method
16
+ @text_method = text_method
17
+ @options = options
18
+ @label = label
19
+ @caption = caption
20
+ @hint = hint
21
+ @form_group = form_group
22
+ @html_attributes = kwargs
23
+
24
+ # FIXME remove this soon, worth informing people who miss the release notes that the
25
+ # args have changed though.
26
+ if :html_options.in?(kwargs.keys)
27
+ warn("GOVUKDesignSystemFormBuilder: html_options has been deprecated, use keyword arguments instead")
28
+ end
29
+ end
30
+
31
+ def html
32
+ Containers::FormGroup.new(*bound, **@form_group).html do
33
+ safe_join([label_element, supplemental_content, hint_element, error_element, collection_select])
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def options
40
+ {
41
+ id: field_id(link_errors: true),
42
+ class: classes,
43
+ aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
44
+ }
45
+ end
46
+
47
+ def collection_select
48
+ @builder.collection_select(@attribute_name, @collection, @value_method, @text_method, @options, **attributes(@html_attributes))
49
+ end
50
+ end
51
+ end
52
+ end
@@ -72,7 +72,19 @@ module GOVUKDesignSystemFormBuilder
72
72
  def value(segment)
73
73
  attribute = @builder.object.try(@attribute_name)
74
74
 
75
- attribute.try(segment) || attribute.try(:[], MULTIPARAMETER_KEY[segment])
75
+ return unless attribute
76
+
77
+ if attribute.respond_to?(segment)
78
+ attribute.send(segment)
79
+ elsif attribute.respond_to?(:fetch)
80
+ attribute.fetch(MULTIPARAMETER_KEY[segment]) do
81
+ warn("No key '#{segment}' found in MULTIPARAMETER_KEY hash. Expected to find #{MULTIPARAMETER_KEY.values}")
82
+
83
+ nil
84
+ end
85
+ else
86
+ fail(ArgumentError, "invalid Date-like object: must be a Date, Time, DateTime or Hash in MULTIPARAMETER_KEY format")
87
+ end
76
88
  end
77
89
 
78
90
  def label(segment, link_errors)
@@ -48,7 +48,7 @@ module GOVUKDesignSystemFormBuilder
48
48
  def options
49
49
  {
50
50
  id: field_id(link_errors: @link_errors),
51
- aria: { describedby: hint_id },
51
+ aria: { describedby: [hint_id] },
52
52
  data: { 'aria-controls' => @conditional_id },
53
53
  class: %w(radios__input).prefix(brand)
54
54
  }
@@ -4,56 +4,43 @@ module GOVUKDesignSystemFormBuilder
4
4
  include Traits::Error
5
5
  include Traits::Label
6
6
  include Traits::Hint
7
- include Traits::Supplemental
8
7
  include Traits::HTMLAttributes
8
+ include Traits::Select
9
9
 
10
- def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, hint:, label:, caption:, form_group:, options: {}, **kwargs, &block)
11
- super(builder, object_name, attribute_name, &block)
10
+ def initialize(builder, object_name, attribute_name, choices, options:, form_group:, label:, hint:, caption:, **kwargs, &block)
11
+ # assign the block to an variable rather than passing to super so
12
+ # we can send it through to #select
13
+ super(builder, object_name, attribute_name)
14
+ @block = block
12
15
 
13
- @collection = collection
14
- @value_method = value_method
15
- @text_method = text_method
16
- @options = options
16
+ @form_group = form_group
17
+ @hint = hint
17
18
  @label = label
18
19
  @caption = caption
19
- @hint = hint
20
- @form_group = form_group
20
+ @choices = choices
21
+ @options = options
21
22
  @html_attributes = kwargs
22
-
23
- # FIXME remove this soon, worth informing people who miss the release notes that the
24
- # args have changed though.
25
- if :html_options.in?(kwargs.keys)
26
- Rails.logger.warn("GOVUKDesignSystemFormBuilder: html_options has been deprecated, use keyword arguments instead")
27
- end
28
23
  end
29
24
 
30
25
  def html
31
26
  Containers::FormGroup.new(*bound, **@form_group).html do
32
- safe_join([label_element, supplemental_content, hint_element, error_element, select])
27
+ safe_join([label_element, hint_element, error_element, select])
33
28
  end
34
29
  end
35
30
 
36
31
  private
37
32
 
38
33
  def select
39
- @builder.collection_select(@attribute_name, @collection, @value_method, @text_method, @options, **attributes(@html_attributes))
34
+ @builder.select(@attribute_name, @choices, @options, attributes(@html_attributes), &@block)
40
35
  end
41
36
 
42
37
  def options
43
38
  {
44
39
  id: field_id(link_errors: true),
45
40
  class: classes,
46
- aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
41
+ aria: { describedby: described_by(hint_id, error_id) }
47
42
  }
48
43
  end
49
-
50
- def classes
51
- [%(#{brand}-select), error_class].flatten.compact
52
- end
53
-
54
- def error_class
55
- %(#{brand}-select--error) if has_errors?
56
- end
57
44
  end
58
45
  end
59
46
  end
@@ -1,8 +1,50 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Traits
3
3
  module HTMLAttributes
4
+ # Attributes eases working with default and custom attributes by
5
+ # * deeply merging them so both the default (required) attributes are
6
+ # present
7
+ # * joins the arrays into strings to maintain Rails 6.0.3 compatibility
8
+ class Attributes
9
+ def initialize(defaults, custom)
10
+ @merged = defaults.deeper_merge(deep_split_values(custom))
11
+ end
12
+
13
+ def to_h
14
+ deep_join_values(@merged)
15
+ end
16
+
17
+ private
18
+
19
+ def deep_split_values(hash)
20
+ hash.each.with_object({}) do |(key, value), result|
21
+ result[key] = case value
22
+ when Hash
23
+ deep_split_values(value)
24
+ when String
25
+ value.split
26
+ else
27
+ value
28
+ end
29
+ end
30
+ end
31
+
32
+ def deep_join_values(hash)
33
+ hash.each.with_object({}) do |(key, value), result|
34
+ result[key] = case value
35
+ when Hash
36
+ deep_join_values(value)
37
+ when Array
38
+ value.uniq.join(' ').presence
39
+ else
40
+ value
41
+ end
42
+ end
43
+ end
44
+ end
45
+
4
46
  def attributes(html_attributes = {})
5
- options.deeper_merge(html_attributes)
47
+ Attributes.new(options, html_attributes).to_h
6
48
  end
7
49
  end
8
50
  end
@@ -0,0 +1,15 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Traits
3
+ module Select
4
+ private
5
+
6
+ def classes
7
+ [%(#{brand}-select), error_class].flatten.compact
8
+ end
9
+
10
+ def error_class
11
+ %(#{brand}-select--error) if has_errors?
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
- VERSION = '2.4.0'.freeze
2
+ VERSION = '2.5.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.4.0
4
+ version: 2.5.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-04-01 00:00:00.000000000 Z
11
+ date: 2021-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep_merge
@@ -30,42 +30,42 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '5.2'
33
+ version: '6.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '5.2'
40
+ version: '6.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activemodel
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '5.2'
47
+ version: '6.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '5.2'
54
+ version: '6.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: activesupport
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '5.2'
61
+ version: '6.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '5.2'
68
+ version: '6.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rubocop-govuk
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -134,14 +134,14 @@ dependencies:
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '4.0'
137
+ version: '5.0'
138
138
  type: :development
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '4.0'
144
+ version: '5.0'
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: simplecov
147
147
  requirement: !ruby/object:Gem::Requirement
@@ -255,19 +255,19 @@ dependencies:
255
255
  - !ruby/object:Gem::Version
256
256
  version: 4.1.0
257
257
  - !ruby/object:Gem::Dependency
258
- name: puma
258
+ name: webrick
259
259
  requirement: !ruby/object:Gem::Requirement
260
260
  requirements:
261
261
  - - "~>"
262
262
  - !ruby/object:Gem::Version
263
- version: '5.2'
263
+ version: 1.7.0
264
264
  type: :development
265
265
  prerelease: false
266
266
  version_requirements: !ruby/object:Gem::Requirement
267
267
  requirements:
268
268
  - - "~>"
269
269
  - !ruby/object:Gem::Version
270
- version: '5.2'
270
+ version: 1.7.0
271
271
  description: A Rails form builder that generates form inputs adhering to the GOV.UK
272
272
  Design System
273
273
  email:
@@ -295,6 +295,7 @@ files:
295
295
  - lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb
296
296
  - lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb
297
297
  - lib/govuk_design_system_formbuilder/elements/check_boxes/label.rb
298
+ - lib/govuk_design_system_formbuilder/elements/collection_select.rb
298
299
  - lib/govuk_design_system_formbuilder/elements/date.rb
299
300
  - lib/govuk_design_system_formbuilder/elements/error_message.rb
300
301
  - lib/govuk_design_system_formbuilder/elements/error_summary.rb
@@ -325,6 +326,7 @@ files:
325
326
  - lib/govuk_design_system_formbuilder/traits/input.rb
326
327
  - lib/govuk_design_system_formbuilder/traits/label.rb
327
328
  - lib/govuk_design_system_formbuilder/traits/localisation.rb
329
+ - lib/govuk_design_system_formbuilder/traits/select.rb
328
330
  - lib/govuk_design_system_formbuilder/traits/supplemental.rb
329
331
  - lib/govuk_design_system_formbuilder/version.rb
330
332
  homepage: https://govuk-form-builder.netlify.app
@@ -351,7 +353,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
351
353
  - !ruby/object:Gem::Version
352
354
  version: '0'
353
355
  requirements: []
354
- rubygems_version: 3.1.4
356
+ rubygems_version: 3.1.6
355
357
  signing_key:
356
358
  specification_version: 4
357
359
  summary: GOV.UK-compliant Rails form builder