govuk_design_system_formbuilder 1.1.10 → 1.2.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.
Files changed (42) 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 +12 -0
  5. data/lib/govuk_design_system_formbuilder/builder.rb +311 -74
  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 +3 -2
  9. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +37 -16
  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 +3 -2
  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 +3 -2
  15. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +5 -3
  16. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +7 -4
  17. data/lib/govuk_design_system_formbuilder/elements/check_boxes/label.rb +8 -2
  18. data/lib/govuk_design_system_formbuilder/elements/date.rb +15 -11
  19. data/lib/govuk_design_system_formbuilder/elements/error_message.rb +4 -2
  20. data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +4 -4
  21. data/lib/govuk_design_system_formbuilder/elements/file.rb +6 -3
  22. data/lib/govuk_design_system_formbuilder/elements/hint.rb +5 -3
  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 +30 -20
  30. data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +3 -2
  31. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +4 -2
  32. data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +7 -4
  33. data/lib/govuk_design_system_formbuilder/elements/select.rb +6 -3
  34. data/lib/govuk_design_system_formbuilder/elements/submit.rb +10 -7
  35. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +12 -5
  36. data/lib/govuk_design_system_formbuilder/traits/caption.rb +24 -0
  37. data/lib/govuk_design_system_formbuilder/traits/input.rb +16 -16
  38. data/lib/govuk_design_system_formbuilder/traits/label.rb +12 -1
  39. data/lib/govuk_design_system_formbuilder/traits/localisation.rb +18 -10
  40. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  41. metadata +16 -43
  42. data/lib/govuk_design_system_formbuilder/elements/check_boxes/hint.rb +0 -32
@@ -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,7 +17,7 @@ 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
+ Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_element.error_id, hint_element.hint_id]).html do
20
21
  safe_join(
21
22
  [
22
23
  hint_element.html,
@@ -1,59 +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)
9
- super(builder, object_name, attribute_name)
11
+ def initialize(builder, object_name = nil, attribute_name = nil, legend: {}, caption: {}, described_by: nil, &block)
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, 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
- text: nil,
27
- tag: config.default_legend_tag,
28
- size: config.default_legend_size
29
- }
36
+ def legend_content
37
+ @legend_raw || build_legend
30
38
  end
31
39
 
32
40
  def build_legend
33
41
  if legend_text.present?
34
42
  content_tag('legend', class: legend_classes) do
35
- 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.html, legend_text])
45
+ end
36
46
  end
37
47
  end
38
48
  end
39
49
 
40
50
  def legend_text
41
- [@legend.dig(:text), localised_text(:legend)].compact.first
51
+ [@legend_options.dig(:text), localised_text(:legend)].compact.first
42
52
  end
43
53
 
44
54
  def fieldset_classes
45
- %w(govuk-fieldset)
55
+ %w(fieldset).prefix(brand)
46
56
  end
47
57
 
48
58
  def legend_classes
49
- size = @legend.dig(:size)
59
+ size = @legend_options.dig(:size)
50
60
  fail "invalid size '#{size}', must be #{LEGEND_SIZES.join(', ')}" unless size.in?(LEGEND_SIZES)
51
61
 
52
- ["govuk-fieldset__legend", "govuk-fieldset__legend--#{size}"]
62
+ [%(fieldset__legend), %(fieldset__legend--#{size})].prefix(brand).tap do |classes|
63
+ classes.push(%(#{brand}-visually-hidden)) if @legend_options.dig(:hidden)
64
+ end
53
65
  end
54
66
 
55
67
  def legend_heading_classes
56
- %(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
+ }
57
78
  end
58
79
  end
59
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,7 +18,7 @@ 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
+ 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
22
  safe_join(
22
23
  [
23
24
  hint_element.html,
@@ -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,13 +15,14 @@ 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
+ Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id]).html do
25
26
  safe_join(
26
27
  [
27
28
  supplemental_content.html,
@@ -2,6 +2,8 @@ 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
 
@@ -16,12 +18,12 @@ module GOVUKDesignSystemFormBuilder
16
18
  end
17
19
 
18
20
  def html
19
- content_tag('div', class: 'govuk-checkboxes__item') do
21
+ content_tag('div', class: %(#{brand}-checkboxes__item)) do
20
22
  safe_join(
21
23
  [
22
24
  @checkbox.check_box(
23
25
  id: field_id(link_errors: @link_errors),
24
- class: "govuk-checkboxes__input",
26
+ class: %(#{brand}-checkboxes__input),
25
27
  aria: { describedby: hint_id }
26
28
  ),
27
29
  label_element.html,
@@ -38,7 +40,7 @@ module GOVUKDesignSystemFormBuilder
38
40
  end
39
41
 
40
42
  def hint_element
41
- @hint_element ||= Hint.new(@builder, @object_name, @attribute_name, @hint_text, value: @value)
43
+ @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text, @value, checkbox: true)
42
44
  end
43
45
  end
44
46
  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
 
@@ -23,7 +26,7 @@ module GOVUKDesignSystemFormBuilder
23
26
  def html
24
27
  safe_join(
25
28
  [
26
- content_tag('div', class: 'govuk-checkboxes__item') do
29
+ content_tag('div', class: %(#{brand}-checkboxes__item)) do
27
30
  safe_join(
28
31
  [
29
32
  input,
@@ -55,7 +58,7 @@ module GOVUKDesignSystemFormBuilder
55
58
  end
56
59
 
57
60
  def label_element
58
- @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, checkbox: true, value: @value, **@label, link_errors: @link_errors)
61
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, checkbox: true, value: @value, link_errors: @link_errors, **label_args)
59
62
  end
60
63
 
61
64
  def hint_element
@@ -63,11 +66,11 @@ module GOVUKDesignSystemFormBuilder
63
66
  end
64
67
 
65
68
  def conditional_classes
66
- %w(govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden)
69
+ %w(checkboxes__conditional checkboxes__conditional--hidden).prefix(brand)
67
70
  end
68
71
 
69
72
  def check_box_classes
70
- %w(govuk-checkboxes__input)
73
+ %w(checkboxes__input).prefix(brand)
71
74
  end
72
75
  end
73
76
  end
@@ -2,6 +2,10 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module CheckBoxes
4
4
  class Label < Base
5
+ using PrefixableArray
6
+
7
+ include Traits::Localisation
8
+
5
9
  def initialize(builder, object_name, attribute_name, checkbox, value:, link_errors: true)
6
10
  super(builder, object_name, attribute_name)
7
11
 
@@ -11,13 +15,15 @@ module GOVUKDesignSystemFormBuilder
11
15
  end
12
16
 
13
17
  def html
14
- @checkbox.label(for: field_id(link_errors: @link_errors), class: label_classes)
18
+ @checkbox.label(for: field_id(link_errors: @link_errors), class: label_classes) do
19
+ [localised_text(:label), @checkbox.text, @value].compact.first
20
+ end
15
21
  end
16
22
 
17
23
  private
18
24
 
19
25
  def label_classes
20
- %w(govuk-label govuk-checkboxes__label)
26
+ %w(label checkboxes__label).prefix(brand)
21
27
  end
22
28
  end
23
29
  end
@@ -1,16 +1,19 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  class Date < Base
4
+ using PrefixableArray
5
+
4
6
  include Traits::Error
5
7
  include Traits::Hint
6
8
  include Traits::Supplemental
7
9
 
8
10
  SEGMENTS = { day: '3i', month: '2i', year: '1i' }.freeze
9
11
 
10
- def initialize(builder, object_name, attribute_name, legend:, hint_text:, date_of_birth: false, omit_day:, &block)
12
+ def initialize(builder, object_name, attribute_name, legend:, caption:, hint_text:, date_of_birth: false, omit_day:, &block)
11
13
  super(builder, object_name, attribute_name, &block)
12
14
 
13
15
  @legend = legend
16
+ @caption = caption
14
17
  @hint_text = hint_text
15
18
  @date_of_birth = date_of_birth
16
19
  @omit_day = omit_day
@@ -18,13 +21,13 @@ module GOVUKDesignSystemFormBuilder
18
21
 
19
22
  def html
20
23
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
21
- Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, described_by: [error_id, hint_id, supplemental_id]).html do
24
+ Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id]).html do
22
25
  safe_join(
23
26
  [
24
27
  supplemental_content.html,
25
28
  hint_element.html,
26
29
  error_element.html,
27
- content_tag('div', class: 'govuk-date-input') do
30
+ content_tag('div', class: %(#{brand}-date-input)) do
28
31
  safe_join([day, month, year])
29
32
  end
30
33
  ]
@@ -56,8 +59,8 @@ module GOVUKDesignSystemFormBuilder
56
59
  def date_input_item(segment, width: 2, link_errors: false)
57
60
  value = @builder.object.try(@attribute_name).try(segment)
58
61
 
59
- content_tag('div', class: %w(govuk-date-input__item)) do
60
- content_tag('div', class: %w(govuk-form-group)) do
62
+ content_tag('div', class: %w(date-input__item).prefix(brand)) do
63
+ content_tag('div', class: %w(form-group).prefix(brand)) do
61
64
  safe_join(
62
65
  [
63
66
  tag.label(
@@ -83,14 +86,14 @@ module GOVUKDesignSystemFormBuilder
83
86
  end
84
87
 
85
88
  def date_input_classes(width)
86
- %w(govuk-input govuk-date-input__input).tap do |classes|
87
- classes.push("govuk-input--width-#{width}")
88
- classes.push("govuk-input--error") if has_errors?
89
+ %w(input date-input__input).prefix(brand).tap do |classes|
90
+ classes.push(%(#{brand}-input--width-#{width}))
91
+ classes.push(%(#{brand}-input--error)) if has_errors?
89
92
  end
90
93
  end
91
94
 
92
95
  def date_input_label_classes
93
- %w(govuk-label govuk-date-input__label)
96
+ %w(label date-input__label).prefix(brand)
94
97
  end
95
98
 
96
99
  # if the field has errors we want the govuk_error_summary to
@@ -105,11 +108,12 @@ module GOVUKDesignSystemFormBuilder
105
108
  end
106
109
 
107
110
  def date_attribute_name(segment)
108
- "%<object_name>s[%<attribute_name>s(%<segment>s)]" % {
111
+ format(
112
+ "%<object_name>s[%<attribute_name>s(%<segment>s)]",
109
113
  object_name: @object_name,
110
114
  attribute_name: @attribute_name,
111
115
  segment: SEGMENTS.fetch(segment)
112
- }
116
+ )
113
117
  end
114
118
 
115
119
  def date_of_birth_autocomplete_value(segment)