govuk_design_system_formbuilder 1.1.11 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/govuk_design_system_formbuilder.rb +7 -1
  4. data/lib/govuk_design_system_formbuilder/base.rb +17 -0
  5. data/lib/govuk_design_system_formbuilder/builder.rb +205 -77
  6. data/lib/govuk_design_system_formbuilder/containers/character_count.rb +2 -2
  7. data/lib/govuk_design_system_formbuilder/containers/check_boxes.rb +5 -3
  8. data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +12 -11
  9. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +37 -20
  10. data/lib/govuk_design_system_formbuilder/containers/form_group.rb +4 -2
  11. data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +12 -11
  12. data/lib/govuk_design_system_formbuilder/containers/radios.rb +7 -5
  13. data/lib/govuk_design_system_formbuilder/elements/caption.rb +34 -0
  14. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +11 -13
  15. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +20 -16
  16. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +24 -29
  17. data/lib/govuk_design_system_formbuilder/elements/check_boxes/label.rb +3 -1
  18. data/lib/govuk_design_system_formbuilder/elements/date.rb +31 -31
  19. data/lib/govuk_design_system_formbuilder/elements/error_message.rb +11 -8
  20. data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +26 -29
  21. data/lib/govuk_design_system_formbuilder/elements/file.rb +22 -21
  22. data/lib/govuk_design_system_formbuilder/elements/hint.rb +6 -7
  23. data/lib/govuk_design_system_formbuilder/elements/inputs/email.rb +2 -0
  24. data/lib/govuk_design_system_formbuilder/elements/inputs/number.rb +2 -0
  25. data/lib/govuk_design_system_formbuilder/elements/inputs/password.rb +2 -0
  26. data/lib/govuk_design_system_formbuilder/elements/inputs/phone.rb +2 -0
  27. data/lib/govuk_design_system_formbuilder/elements/inputs/text.rb +2 -0
  28. data/lib/govuk_design_system_formbuilder/elements/inputs/url.rb +2 -0
  29. data/lib/govuk_design_system_formbuilder/elements/label.rb +39 -26
  30. data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +26 -24
  31. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +16 -14
  32. data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +19 -21
  33. data/lib/govuk_design_system_formbuilder/elements/select.rb +12 -20
  34. data/lib/govuk_design_system_formbuilder/elements/submit.rb +29 -27
  35. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +27 -27
  36. data/lib/govuk_design_system_formbuilder/traits/caption.rb +23 -0
  37. data/lib/govuk_design_system_formbuilder/traits/input.rb +33 -41
  38. data/lib/govuk_design_system_formbuilder/traits/label.rb +12 -1
  39. data/lib/govuk_design_system_formbuilder/traits/localisation.rb +2 -0
  40. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  41. metadata +19 -17
@@ -16,8 +16,8 @@ module GOVUKDesignSystemFormBuilder
16
16
 
17
17
  content_tag(
18
18
  'div',
19
- class: 'govuk-character-count',
20
- data: { module: 'govuk-character-count' }.merge(**limit, **threshold).compact
19
+ class: %(#{brand}-character-count),
20
+ data: { module: %(#{brand}-character-count) }.merge(**limit, **threshold).compact
21
21
  ) do
22
22
  yield
23
23
  end
@@ -1,6 +1,8 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Containers
3
3
  class CheckBoxes < Base
4
+ using PrefixableArray
5
+
4
6
  def initialize(builder, small:, classes: nil)
5
7
  @builder = builder
6
8
  @small = small
@@ -8,7 +10,7 @@ module GOVUKDesignSystemFormBuilder
8
10
  end
9
11
 
10
12
  def html
11
- content_tag('div', class: check_boxes_classes, data: { module: 'govuk-checkboxes' }) do
13
+ content_tag('div', class: check_boxes_classes, data: { module: %(#{brand}-checkboxes) }) do
12
14
  yield
13
15
  end
14
16
  end
@@ -16,8 +18,8 @@ module GOVUKDesignSystemFormBuilder
16
18
  private
17
19
 
18
20
  def check_boxes_classes
19
- %w(govuk-checkboxes).tap do |c|
20
- c.push('govuk-checkboxes--small') if @small
21
+ %w(checkboxes).prefix(brand).tap do |c|
22
+ c.push(%(#{brand}-checkboxes--small)) if @small
21
23
  c.push(@classes) if @classes
22
24
  end
23
25
  end
@@ -4,10 +4,11 @@ module GOVUKDesignSystemFormBuilder
4
4
  include Traits::Error
5
5
  include Traits::Hint
6
6
 
7
- def initialize(builder, object_name, attribute_name, hint_text:, legend:, small:, classes:, &block)
7
+ def initialize(builder, object_name, attribute_name, hint_text:, legend:, caption:, small:, classes:, &block)
8
8
  super(builder, object_name, attribute_name, &block)
9
9
 
10
10
  @legend = legend
11
+ @caption = caption
11
12
  @hint_text = hint_text
12
13
  @small = small
13
14
  @classes = classes
@@ -16,19 +17,19 @@ module GOVUKDesignSystemFormBuilder
16
17
 
17
18
  def html
18
19
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
19
- Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, described_by: [error_element.error_id, hint_element.hint_id]).html do
20
- safe_join(
21
- [
22
- hint_element.html,
23
- error_element.html,
24
- Containers::CheckBoxes.new(@builder, small: @small, classes: @classes).html do
25
- @block_content
26
- end
27
- ]
28
- )
20
+ Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_element.error_id, hint_element.hint_id]).html do
21
+ safe_join([hint_element, error_element, checkboxes])
29
22
  end
30
23
  end
31
24
  end
25
+
26
+ private
27
+
28
+ def checkboxes
29
+ Containers::CheckBoxes.new(@builder, small: @small, classes: @classes).html do
30
+ @block_content
31
+ end
32
+ end
32
33
  end
33
34
  end
34
35
  end
@@ -1,63 +1,80 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Containers
3
3
  class Fieldset < Base
4
+ using PrefixableArray
5
+
6
+ include Traits::Caption
4
7
  include Traits::Localisation
5
8
 
6
9
  LEGEND_SIZES = %w(xl l m s).freeze
7
10
 
8
- def initialize(builder, object_name = nil, attribute_name = nil, legend: {}, described_by: nil, &block)
11
+ def initialize(builder, object_name = nil, attribute_name = nil, legend: {}, caption: {}, described_by: nil, &block)
9
12
  super(builder, object_name, attribute_name, &block)
10
13
 
11
- @legend = legend_defaults.merge(legend)
12
14
  @described_by = described_by(described_by)
13
15
  @attribute_name = attribute_name
16
+
17
+ case legend
18
+ when Proc
19
+ @legend_raw = legend.call
20
+ when Hash
21
+ @legend_options = legend_defaults.merge(legend)
22
+ @caption = caption
23
+ else
24
+ fail(ArgumentError, %(legend must be a Proc or Hash))
25
+ end
14
26
  end
15
27
 
16
28
  def html
17
29
  content_tag('fieldset', class: fieldset_classes, aria: { describedby: @described_by }) do
18
- safe_join([build_legend, (@block_content || yield)])
30
+ safe_join([legend_content, (@block_content || yield)])
19
31
  end
20
32
  end
21
33
 
22
34
  private
23
35
 
24
- def legend_defaults
25
- {
26
- hidden: false,
27
- text: nil,
28
- tag: config.default_legend_tag,
29
- size: config.default_legend_size
30
- }
36
+ def legend_content
37
+ @legend_raw || legend
31
38
  end
32
39
 
33
- def build_legend
40
+ def legend
34
41
  if legend_text.present?
35
42
  content_tag('legend', class: legend_classes) do
36
- tag.send(@legend.dig(:tag), legend_text, class: legend_heading_classes)
43
+ content_tag(@legend_options.dig(:tag), class: legend_heading_classes) do
44
+ safe_join([caption_element, legend_text])
45
+ end
37
46
  end
38
47
  end
39
48
  end
40
49
 
41
50
  def legend_text
42
- [@legend.dig(:text), localised_text(:legend)].compact.first
51
+ [@legend_options.dig(:text), localised_text(:legend)].compact.first
43
52
  end
44
53
 
45
54
  def fieldset_classes
46
- %w(govuk-fieldset)
55
+ %w(fieldset).prefix(brand)
47
56
  end
48
57
 
49
58
  def legend_classes
50
- size = @legend.dig(:size)
59
+ size = @legend_options.dig(:size)
51
60
  fail "invalid size '#{size}', must be #{LEGEND_SIZES.join(', ')}" unless size.in?(LEGEND_SIZES)
52
61
 
53
- classes = %W(govuk-fieldset__legend govuk-fieldset__legend--#{size})
54
- classes.push('govuk-visually-hidden') if @legend.dig(:hidden)
55
-
56
- classes
62
+ [%(fieldset__legend), %(fieldset__legend--#{size})].prefix(brand).tap do |classes|
63
+ classes.push(%(#{brand}-visually-hidden)) if @legend_options.dig(:hidden)
64
+ end
57
65
  end
58
66
 
59
67
  def legend_heading_classes
60
- %(govuk-fieldset__heading)
68
+ %w(fieldset__heading).prefix(brand)
69
+ end
70
+
71
+ def legend_defaults
72
+ {
73
+ hidden: false,
74
+ text: nil,
75
+ tag: config.default_legend_tag,
76
+ size: config.default_legend_size
77
+ }
61
78
  end
62
79
  end
63
80
  end
@@ -1,6 +1,8 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Containers
3
3
  class FormGroup < Base
4
+ using PrefixableArray
5
+
4
6
  def initialize(builder, object_name, attribute_name)
5
7
  super(builder, object_name, attribute_name)
6
8
  end
@@ -14,8 +16,8 @@ module GOVUKDesignSystemFormBuilder
14
16
  private
15
17
 
16
18
  def form_group_classes
17
- %w(govuk-form-group).tap do |classes|
18
- classes.push('govuk-form-group--error') if has_errors?
19
+ %w(form-group).prefix(brand).tap do |classes|
20
+ classes.push(%(#{brand}-form-group--error)) if has_errors?
19
21
  end
20
22
  end
21
23
  end
@@ -4,12 +4,13 @@ module GOVUKDesignSystemFormBuilder
4
4
  include Traits::Hint
5
5
  include Traits::Error
6
6
 
7
- def initialize(builder, object_name, attribute_name, hint_text:, legend:, inline:, small:, classes:, &block)
7
+ def initialize(builder, object_name, attribute_name, hint_text:, legend:, caption:, inline:, small:, classes:, &block)
8
8
  super(builder, object_name, attribute_name)
9
9
 
10
10
  @inline = inline
11
11
  @small = small
12
12
  @legend = legend
13
+ @caption = caption
13
14
  @hint_text = hint_text
14
15
  @classes = classes
15
16
  @block_content = capture { block.call }
@@ -17,19 +18,19 @@ module GOVUKDesignSystemFormBuilder
17
18
 
18
19
  def html
19
20
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
20
- Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, described_by: [error_element.error_id, hint_element.hint_id]).html do
21
- safe_join(
22
- [
23
- hint_element.html,
24
- error_element.html,
25
- Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
26
- @block_content
27
- end
28
- ]
29
- )
21
+ Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_element.error_id, hint_element.hint_id]).html do
22
+ safe_join([hint_element, error_element, radios])
30
23
  end
31
24
  end
32
25
  end
26
+
27
+ private
28
+
29
+ def radios
30
+ Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
31
+ @block_content
32
+ end
33
+ end
33
34
  end
34
35
  end
35
36
  end
@@ -1,6 +1,8 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Containers
3
3
  class Radios < Base
4
+ using PrefixableArray
5
+
4
6
  include Traits::Hint
5
7
 
6
8
  def initialize(builder, inline:, small:, classes:)
@@ -11,7 +13,7 @@ module GOVUKDesignSystemFormBuilder
11
13
  end
12
14
 
13
15
  def html
14
- content_tag('div', class: radios_classes, data: { module: 'govuk-radios' }) do
16
+ content_tag('div', class: radios_classes, data: { module: %(#{brand}-radios) }) do
15
17
  yield
16
18
  end
17
19
  end
@@ -19,10 +21,10 @@ module GOVUKDesignSystemFormBuilder
19
21
  private
20
22
 
21
23
  def radios_classes
22
- %w(govuk-radios).tap do |c|
23
- c.push('govuk-radios--inline') if @inline
24
- c.push('govuk-radios--small') if @small
25
- c.push(@classes) if @classes
24
+ %w(radios).prefix(brand).tap do |c|
25
+ c.push(%(#{brand}-radios--inline)) if @inline
26
+ c.push(%(#{brand}-radios--small)) if @small
27
+ c.push(@classes) if @classes
26
28
  end
27
29
  end
28
30
  end
@@ -0,0 +1,34 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ class Caption < Base
4
+ include Traits::Localisation
5
+
6
+ def initialize(builder, object_name, attribute_name, text:, size: 'm')
7
+ super(builder, object_name, attribute_name)
8
+
9
+ @text = caption_text(text)
10
+ @size_class = caption_size_class(size)
11
+ end
12
+
13
+ def html
14
+ return nil if @text.blank?
15
+
16
+ tag.span(@text, class: @size_class)
17
+ end
18
+
19
+ def caption_text(override)
20
+ override || localised_text(:caption)
21
+ end
22
+
23
+ def caption_size_class(size)
24
+ case size
25
+ when 'xl' then %(#{brand}-caption-xl)
26
+ when 'l' then %(#{brand}-caption-l)
27
+ when 'm' then %(#{brand}-caption-m)
28
+ else
29
+ fail ArgumentError, "invalid size '#{size}', must be xl, l or m"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -6,7 +6,7 @@ module GOVUKDesignSystemFormBuilder
6
6
  include Traits::Hint
7
7
  include Traits::Supplemental
8
8
 
9
- def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, hint_method: nil, hint_text:, legend:, small:, classes:, &block)
9
+ def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, hint_method: nil, hint_text:, legend:, caption:, small:, classes:, &block)
10
10
  super(builder, object_name, attribute_name, &block)
11
11
 
12
12
  @collection = collection
@@ -15,29 +15,27 @@ module GOVUKDesignSystemFormBuilder
15
15
  @hint_method = hint_method
16
16
  @small = small
17
17
  @legend = legend
18
+ @caption = caption
18
19
  @hint_text = hint_text
19
20
  @classes = classes
20
21
  end
21
22
 
22
23
  def html
23
24
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
24
- Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, described_by: [error_id, hint_id, supplemental_id]).html do
25
- safe_join(
26
- [
27
- supplemental_content.html,
28
- hint_element.html,
29
- error_element.html,
30
- Containers::CheckBoxes.new(@builder, small: @small, classes: @classes).html do
31
- build_collection
32
- end
33
- ]
34
- )
25
+ Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id]).html do
26
+ safe_join([supplemental_content, hint_element, error_element, check_boxes])
35
27
  end
36
28
  end
37
29
  end
38
30
 
39
31
  private
40
32
 
33
+ def check_boxes
34
+ Containers::CheckBoxes.new(@builder, small: @small, classes: @classes).html do
35
+ collection
36
+ end
37
+ end
38
+
41
39
  # Builds a collection of check {Elements::CheckBoxes::CheckBox}
42
40
  # @return [ActiveSupport::SafeBuffer] HTML output
43
41
  #
@@ -46,7 +44,7 @@ module GOVUKDesignSystemFormBuilder
46
44
  # be rendered when it happens we need to work on the chance that it might, so
47
45
  # the +link_errors+ variable is set to +true+ if this attribute has errors and
48
46
  # always set back to +false+ after the first checkbox has been rendered
49
- def build_collection
47
+ def collection
50
48
  link_errors = has_errors?
51
49
 
52
50
  @builder.collection_check_boxes(@attribute_name, @collection, @value_method, @text_method) do |check_box|
@@ -2,37 +2,41 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module CheckBoxes
4
4
  class CollectionCheckBox < Base
5
+ using PrefixableArray
6
+
5
7
  include Traits::CollectionItem
6
8
  include Traits::Hint
7
9
 
8
10
  def initialize(builder, object_name, attribute_name, checkbox, hint_method = nil, link_errors: false)
9
11
  super(builder, object_name, attribute_name)
10
12
 
11
- @checkbox = checkbox
12
- @item = checkbox.object
13
- @value = checkbox.value
14
- @hint_text = retrieve(@item, hint_method)
13
+ @checkbox = checkbox
14
+ @item = checkbox.object
15
+ @value = checkbox.value
16
+ @hint_text = retrieve(@item, hint_method)
15
17
  @link_errors = link_errors
16
18
  end
17
19
 
18
20
  def html
19
- content_tag('div', class: 'govuk-checkboxes__item') do
20
- safe_join(
21
- [
22
- @checkbox.check_box(
23
- id: field_id(link_errors: @link_errors),
24
- class: "govuk-checkboxes__input",
25
- aria: { describedby: hint_id }
26
- ),
27
- label_element.html,
28
- hint_element.html
29
- ]
30
- )
21
+ content_tag('div', class: %(#{brand}-checkboxes__item)) do
22
+ safe_join([check_box, label_element, hint_element])
31
23
  end
32
24
  end
33
25
 
34
26
  private
35
27
 
28
+ def check_box
29
+ @checkbox.check_box(**check_box_options)
30
+ end
31
+
32
+ def check_box_options
33
+ {
34
+ id: field_id(link_errors: @link_errors),
35
+ class: %(#{brand}-checkboxes__input),
36
+ aria: { describedby: hint_id }
37
+ }
38
+ end
39
+
36
40
  def label_element
37
41
  @label_element ||= Label.new(@builder, @object_name, @attribute_name, @checkbox, value: @value, link_errors: @link_errors)
38
42
  end
@@ -2,6 +2,9 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module CheckBoxes
4
4
  class FieldsetCheckBox < Base
5
+ using PrefixableArray
6
+
7
+ include Traits::Label
5
8
  include Traits::Hint
6
9
  include Traits::Conditional
7
10
 
@@ -21,41 +24,33 @@ module GOVUKDesignSystemFormBuilder
21
24
  end
22
25
 
23
26
  def html
24
- safe_join(
25
- [
26
- content_tag('div', class: 'govuk-checkboxes__item') do
27
- safe_join(
28
- [
29
- input,
30
- label_element.html,
31
- hint_element.html,
32
- ]
33
- )
34
- end,
35
- @conditional_content
36
- ]
37
- )
27
+ safe_join([check_box, @conditional_content])
38
28
  end
39
29
 
40
30
  private
41
31
 
32
+ def check_box
33
+ content_tag('div', class: %(#{brand}-checkboxes__item)) do
34
+ safe_join([input, label_element, hint_element])
35
+ end
36
+ end
37
+
42
38
  def input
43
- @builder.check_box(
44
- @attribute_name,
45
- {
46
- id: field_id(link_errors: @link_errors),
47
- class: check_box_classes,
48
- multiple: @multiple,
49
- aria: { describedby: hint_id },
50
- data: { 'aria-controls' => @conditional_id }
51
- },
52
- @value,
53
- false
54
- )
39
+ @builder.check_box(@attribute_name, input_options, @value, false)
40
+ end
41
+
42
+ def input_options
43
+ {
44
+ id: field_id(link_errors: @link_errors),
45
+ class: check_box_classes,
46
+ multiple: @multiple,
47
+ aria: { describedby: hint_id },
48
+ data: { 'aria-controls' => @conditional_id }
49
+ }
55
50
  end
56
51
 
57
52
  def label_element
58
- @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, checkbox: true, value: @value, **@label, link_errors: @link_errors)
53
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, checkbox: true, value: @value, link_errors: @link_errors, **label_options)
59
54
  end
60
55
 
61
56
  def hint_element
@@ -63,11 +58,11 @@ module GOVUKDesignSystemFormBuilder
63
58
  end
64
59
 
65
60
  def conditional_classes
66
- %w(govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden)
61
+ %w(checkboxes__conditional checkboxes__conditional--hidden).prefix(brand)
67
62
  end
68
63
 
69
64
  def check_box_classes
70
- %w(govuk-checkboxes__input)
65
+ %w(checkboxes__input).prefix(brand)
71
66
  end
72
67
  end
73
68
  end