govuk_design_system_formbuilder 1.1.9 → 1.2.0b4

Sign up to get free protection for your applications and to get access to all the features.
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 -8
  40. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  41. metadata +18 -45
  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)