govuk_design_system_formbuilder 1.2.3 → 1.2.9

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 +1 -1
  4. data/lib/govuk_design_system_formbuilder/base.rb +1 -1
  5. data/lib/govuk_design_system_formbuilder/builder.rb +53 -31
  6. data/lib/govuk_design_system_formbuilder/containers/character_count.rb +8 -7
  7. data/lib/govuk_design_system_formbuilder/containers/check_boxes.rb +18 -10
  8. data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +18 -9
  9. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +15 -55
  10. data/lib/govuk_design_system_formbuilder/containers/form_group.rb +18 -10
  11. data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +19 -10
  12. data/lib/govuk_design_system_formbuilder/containers/radios.rb +22 -11
  13. data/lib/govuk_design_system_formbuilder/containers/supplemental.rb +3 -3
  14. data/lib/govuk_design_system_formbuilder/elements/caption.rb +6 -4
  15. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +21 -12
  16. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +3 -5
  17. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +24 -19
  18. data/lib/govuk_design_system_formbuilder/elements/date.rb +51 -44
  19. data/lib/govuk_design_system_formbuilder/elements/error_message.rb +4 -4
  20. data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +15 -15
  21. data/lib/govuk_design_system_formbuilder/elements/file.rb +11 -10
  22. data/lib/govuk_design_system_formbuilder/elements/hint.rb +13 -13
  23. data/lib/govuk_design_system_formbuilder/elements/inputs/email.rb +2 -2
  24. data/lib/govuk_design_system_formbuilder/elements/inputs/number.rb +0 -2
  25. data/lib/govuk_design_system_formbuilder/elements/inputs/password.rb +0 -2
  26. data/lib/govuk_design_system_formbuilder/elements/inputs/phone.rb +0 -2
  27. data/lib/govuk_design_system_formbuilder/elements/inputs/text.rb +0 -2
  28. data/lib/govuk_design_system_formbuilder/elements/inputs/url.rb +0 -2
  29. data/lib/govuk_design_system_formbuilder/elements/label.rb +30 -26
  30. data/lib/govuk_design_system_formbuilder/elements/legend.rb +79 -0
  31. data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +23 -14
  32. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +15 -7
  33. data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +8 -4
  34. data/lib/govuk_design_system_formbuilder/elements/select.rb +24 -19
  35. data/lib/govuk_design_system_formbuilder/elements/submit.rb +11 -6
  36. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +31 -25
  37. data/lib/govuk_design_system_formbuilder/traits/collection_item.rb +1 -1
  38. data/lib/govuk_design_system_formbuilder/traits/conditional.rb +1 -1
  39. data/lib/govuk_design_system_formbuilder/traits/input.rb +9 -8
  40. data/lib/govuk_design_system_formbuilder/traits/label.rb +2 -2
  41. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  42. metadata +14 -13
@@ -12,18 +12,18 @@ module GOVUKDesignSystemFormBuilder
12
12
  def html
13
13
  return nil unless has_errors?
14
14
 
15
- content_tag('span', class: %(#{brand}-error-message), id: error_id) do
16
- safe_join([error_prefix, error_message])
15
+ tag.span(class: %(#{brand}-error-message), id: error_id) do
16
+ safe_join([hidden_prefix, message])
17
17
  end
18
18
  end
19
19
 
20
20
  private
21
21
 
22
- def error_prefix
22
+ def hidden_prefix
23
23
  tag.span('Error: ', class: %(#{brand}-visually-hidden))
24
24
  end
25
25
 
26
- def error_message
26
+ def message
27
27
  @builder.object.errors.messages[@attribute_name]&.first
28
28
  end
29
29
  end
@@ -12,32 +12,32 @@ module GOVUKDesignSystemFormBuilder
12
12
  def html
13
13
  return nil unless object_has_errors?
14
14
 
15
- content_tag('div', class: error_summary_class, **error_summary_options) do
16
- safe_join([error_title, error_summary])
15
+ tag.div(class: summary_class, **summary_options) do
16
+ safe_join([title, summary])
17
17
  end
18
18
  end
19
19
 
20
20
  private
21
21
 
22
- def error_title
23
- tag.h2(@title, id: error_summary_title_id, class: error_summary_class('title'))
22
+ def title
23
+ tag.h2(@title, id: summary_title_id, class: summary_class('title'))
24
24
  end
25
25
 
26
- def error_summary
27
- content_tag('div', class: error_summary_class('body')) do
28
- content_tag('ul', class: [%(#{brand}-list), error_summary_class('list')]) do
29
- safe_join(error_list)
26
+ def summary
27
+ tag.div(class: summary_class('body')) do
28
+ tag.ul(class: [%(#{brand}-list), summary_class('list')]) do
29
+ safe_join(list)
30
30
  end
31
31
  end
32
32
  end
33
33
 
34
- def error_list
34
+ def list
35
35
  @builder.object.errors.messages.map do |attribute, messages|
36
- error_list_item(attribute, messages.first)
36
+ list_item(attribute, messages.first)
37
37
  end
38
38
  end
39
39
 
40
- def error_list_item(attribute, message)
40
+ def list_item(attribute, message)
41
41
  tag.li(link_to(message, same_page_link(field_id(attribute)), data: { turbolinks: false }))
42
42
  end
43
43
 
@@ -45,7 +45,7 @@ module GOVUKDesignSystemFormBuilder
45
45
  '#'.concat(target)
46
46
  end
47
47
 
48
- def error_summary_class(part = nil)
48
+ def summary_class(part = nil)
49
49
  if part
50
50
  %(#{brand}-error-summary).concat('__', part)
51
51
  else
@@ -57,7 +57,7 @@ module GOVUKDesignSystemFormBuilder
57
57
  build_id('field-error', attribute_name: attribute)
58
58
  end
59
59
 
60
- def error_summary_title_id
60
+ def summary_title_id
61
61
  'error-summary-title'
62
62
  end
63
63
 
@@ -65,7 +65,7 @@ module GOVUKDesignSystemFormBuilder
65
65
  @builder.object.errors.any?
66
66
  end
67
67
 
68
- def error_summary_options
68
+ def summary_options
69
69
  {
70
70
  tabindex: -1,
71
71
  role: 'alert',
@@ -73,7 +73,7 @@ module GOVUKDesignSystemFormBuilder
73
73
  module: %(#{brand}-error-summary)
74
74
  },
75
75
  aria: {
76
- labelledby: error_summary_title_id
76
+ labelledby: summary_title_id
77
77
  }
78
78
  }
79
79
  end
@@ -8,17 +8,18 @@ module GOVUKDesignSystemFormBuilder
8
8
  include Traits::Label
9
9
  include Traits::Supplemental
10
10
 
11
- def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, **kwargs, &block)
11
+ def initialize(builder, object_name, attribute_name, hint_text:, label:, caption:, form_group_classes:, **kwargs, &block)
12
12
  super(builder, object_name, attribute_name, &block)
13
13
 
14
- @label = label
15
- @caption = caption
16
- @hint_text = hint_text
17
- @extra_options = kwargs
14
+ @label = label
15
+ @caption = caption
16
+ @hint_text = hint_text
17
+ @extra_options = kwargs
18
+ @form_group_classes = form_group_classes
18
19
  end
19
20
 
20
21
  def html
21
- Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
22
+ Containers::FormGroup.new(@builder, @object_name, @attribute_name, classes: @form_group_classes).html do
22
23
  safe_join([label_element, supplemental_content, hint_element, error_element, file])
23
24
  end
24
25
  end
@@ -26,18 +27,18 @@ module GOVUKDesignSystemFormBuilder
26
27
  private
27
28
 
28
29
  def file
29
- @builder.file_field(@attribute_name, **file_options, **@extra_options)
30
+ @builder.file_field(@attribute_name, **options, **@extra_options)
30
31
  end
31
32
 
32
- def file_options
33
+ def options
33
34
  {
34
35
  id: field_id(link_errors: true),
35
- class: file_classes,
36
+ class: classes,
36
37
  aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
37
38
  }
38
39
  end
39
40
 
40
- def file_classes
41
+ def classes
41
42
  %w(file-upload).prefix(brand).tap do |c|
42
43
  c.push(%(#{brand}-file-upload--error)) if has_errors?
43
44
  end
@@ -9,34 +9,34 @@ module GOVUKDesignSystemFormBuilder
9
9
  def initialize(builder, object_name, attribute_name, text, value = nil, radio: false, checkbox: false)
10
10
  super(builder, object_name, attribute_name)
11
11
 
12
- @value = value
13
- @hint_text = hint_text(text)
14
- @radio_class = radio_class(radio)
15
- @checkbox_class = checkbox_class(checkbox)
12
+ @value = value
13
+ @hint_text = retrieve_text(text)
14
+ @radio = radio
15
+ @checkbox = checkbox
16
16
  end
17
17
 
18
18
  def html
19
19
  return nil if @hint_text.blank?
20
20
 
21
- tag.span(@hint_text, class: hint_classes, id: hint_id)
21
+ tag.span(@hint_text, class: classes, id: hint_id)
22
22
  end
23
23
 
24
24
  private
25
25
 
26
- def hint_text(supplied)
27
- [supplied.presence, localised_text(:hint)].compact.first
26
+ def retrieve_text(supplied)
27
+ supplied.presence || localised_text(:hint)
28
28
  end
29
29
 
30
- def hint_classes
31
- %w(hint).prefix(brand).push(@radio_class, @checkbox_class).compact
30
+ def classes
31
+ %w(hint).prefix(brand).push(radio_class, checkbox_class).compact
32
32
  end
33
33
 
34
- def radio_class(radio)
35
- radio ? %(#{brand}-radios__hint) : nil
34
+ def radio_class
35
+ @radio ? %(#{brand}-radios__hint) : nil
36
36
  end
37
37
 
38
- def checkbox_class(checkbox)
39
- checkbox ? %(#{brand}-checkboxes__hint) : nil
38
+ def checkbox_class
39
+ @checkbox ? %(#{brand}-checkboxes__hint) : nil
40
40
  end
41
41
  end
42
42
  end
@@ -2,14 +2,14 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Inputs
4
4
  class Email < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Input
8
6
  include Traits::Error
9
7
  include Traits::Hint
10
8
  include Traits::Label
11
9
  include Traits::Supplemental
12
10
 
11
+ private
12
+
13
13
  def builder_method
14
14
  :email_field
15
15
  end
@@ -2,8 +2,6 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Inputs
4
4
  class Number < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Input
8
6
  include Traits::Error
9
7
  include Traits::Hint
@@ -2,8 +2,6 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Inputs
4
4
  class Password < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Input
8
6
  include Traits::Error
9
7
  include Traits::Hint
@@ -2,8 +2,6 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Inputs
4
4
  class Phone < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Input
8
6
  include Traits::Error
9
7
  include Traits::Hint
@@ -2,8 +2,6 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Inputs
4
4
  class Text < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Input
8
6
  include Traits::Error
9
7
  include Traits::Hint
@@ -2,8 +2,6 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Inputs
4
4
  class URL < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Input
8
6
  include Traits::Error
9
7
  include Traits::Hint
@@ -12,16 +12,16 @@ module GOVUKDesignSystemFormBuilder
12
12
  # content is passed in directly via a proc and overrides
13
13
  # the other display options
14
14
  if content
15
- @content = content.call
15
+ @content = capture { content.call }
16
16
  else
17
- @value = value # used by field_id
18
- @text = label_text(text, hidden)
19
- @size_class = label_size_class(size)
20
- @radio_class = radio_class(radio)
21
- @checkbox_class = checkbox_class(checkbox)
22
- @tag = tag
23
- @link_errors = link_errors
24
- @caption = caption
17
+ @value = value # used by field_id
18
+ @text = retrieve_text(text, hidden)
19
+ @size_class = size_class(size)
20
+ @radio = radio
21
+ @checkbox = checkbox
22
+ @tag = tag
23
+ @link_errors = link_errors
24
+ @caption = caption
25
25
  end
26
26
  end
27
27
 
@@ -38,48 +38,52 @@ module GOVUKDesignSystemFormBuilder
38
38
  private
39
39
 
40
40
  def label
41
- @builder.label(@attribute_name, label_options) do
41
+ @builder.label(@attribute_name, **options) do
42
42
  @content || safe_join([caption, @text])
43
43
  end
44
44
  end
45
45
 
46
- def label_text(option_text, hidden)
47
- text = [option_text, localised_text(:label), @attribute_name.capitalize].compact.first.to_s
46
+ def retrieve_text(option_text, hidden)
47
+ text = [option_text, localised_text(:label), @attribute_name.capitalize].compact.first
48
48
 
49
49
  if hidden
50
- tag.span(text, class: %w(visually-hidden).prefix(brand))
50
+ tag.span(text, class: %(#{brand}-visually-hidden))
51
51
  else
52
52
  text
53
53
  end
54
54
  end
55
55
 
56
- def label_options
56
+ def options
57
57
  {
58
58
  value: @value,
59
59
  for: field_id(link_errors: @link_errors),
60
- class: %w(label).prefix(brand).push(@size_class, @weight_class, @radio_class, @checkbox_class).compact
60
+ class: %w(label).prefix(brand).push(@size_class, @weight_class, radio_class, checkbox_class).compact
61
61
  }
62
62
  end
63
63
 
64
64
  def caption
65
- caption_element.html unless [@radio_class, @checkbox_class].any?
65
+ caption_element.html unless [@radio, @checkbox].any?
66
66
  end
67
67
 
68
- def radio_class(radio)
69
- radio ? %(#{brand}-radios__label) : nil
68
+ def radio_class
69
+ return nil unless @radio
70
+
71
+ %(#{brand}-radios__label)
70
72
  end
71
73
 
72
- def checkbox_class(checkbox)
73
- checkbox ? %(#{brand}-checkboxes__label) : nil
74
+ def checkbox_class
75
+ return nil unless @checkbox
76
+
77
+ %(#{brand}-checkboxes__label)
74
78
  end
75
79
 
76
- def label_size_class(size)
80
+ def size_class(size)
77
81
  case size
78
- when 'xl' then %(#{brand}-label--xl)
79
- when 'l' then %(#{brand}-label--l)
80
- when 'm' then %(#{brand}-label--m)
81
- when 's' then %(#{brand}-label--s)
82
- when nil then nil
82
+ when 'xl' then %(#{brand}-label--xl)
83
+ when 'l' then %(#{brand}-label--l)
84
+ when 'm' then %(#{brand}-label--m)
85
+ when 's' then %(#{brand}-label--s)
86
+ when nil then nil
83
87
  else
84
88
  fail "invalid size '#{size}', must be xl, l, m, s or nil"
85
89
  end
@@ -0,0 +1,79 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ class Legend < Base
4
+ include Traits::Caption
5
+ include Traits::Localisation
6
+
7
+ def initialize(builder, object_name, attribute_name, legend:, caption:)
8
+ super(builder, object_name, attribute_name)
9
+
10
+ case legend
11
+ when Proc
12
+ @raw = capture { legend.call }
13
+ when Hash
14
+ defaults.merge(legend).tap do |l|
15
+ @text = text(l.dig(:text))
16
+ @hidden = l.dig(:hidden)
17
+ @tag = l.dig(:tag)
18
+ @size = l.dig(:size)
19
+ @caption = caption
20
+ end
21
+ else
22
+ fail(ArgumentError, %(legend must be a Proc or Hash))
23
+ end
24
+ end
25
+
26
+ def html
27
+ @raw || content
28
+ end
29
+
30
+ private
31
+
32
+ def content
33
+ if @text.present?
34
+ tag.legend(class: classes) do
35
+ content_tag(@tag, class: heading_classes) do
36
+ safe_join([caption_element, @text])
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ def text(supplied_text)
43
+ supplied_text || localised_text(:legend)
44
+ end
45
+
46
+ def classes
47
+ [%(#{brand}-fieldset__legend), size_class, visually_hidden_class].compact
48
+ end
49
+
50
+ def size_class
51
+ case @size
52
+ when 'xl' then %(#{brand}-fieldset__legend--xl)
53
+ when 'l' then %(#{brand}-fieldset__legend--l)
54
+ when 'm' then %(#{brand}-fieldset__legend--m)
55
+ when 's' then %(#{brand}-fieldset__legend--s)
56
+ else
57
+ fail "invalid size '#{@size}', must be xl, l, m or s"
58
+ end
59
+ end
60
+
61
+ def visually_hidden_class
62
+ %(#{brand}-visually-hidden) if @hidden
63
+ end
64
+
65
+ def heading_classes
66
+ %(#{brand}-fieldset__heading)
67
+ end
68
+
69
+ def defaults
70
+ {
71
+ hidden: false,
72
+ text: nil,
73
+ tag: config.default_legend_tag,
74
+ size: config.default_legend_size
75
+ }
76
+ end
77
+ end
78
+ end
79
+ end
@@ -6,25 +6,26 @@ 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:, hint_text:, legend:, caption:, inline:, small:, bold_labels:, classes:, &block)
9
+ def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, hint_method:, hint_text:, legend:, caption:, inline:, small:, bold_labels:, classes:, form_group_classes:, &block)
10
10
  super(builder, object_name, attribute_name, &block)
11
11
 
12
- @collection = collection
13
- @value_method = value_method
14
- @text_method = text_method
15
- @hint_method = hint_method
16
- @inline = inline
17
- @small = small
18
- @legend = legend
19
- @caption = caption
20
- @hint_text = hint_text
21
- @classes = classes
22
- @bold_labels = hint_method.present? || bold_labels
12
+ @collection = collection
13
+ @value_method = value_method
14
+ @text_method = text_method
15
+ @hint_method = hint_method
16
+ @inline = inline
17
+ @small = small
18
+ @legend = legend
19
+ @caption = caption
20
+ @hint_text = hint_text
21
+ @classes = classes
22
+ @form_group_classes = form_group_classes
23
+ @bold_labels = hint_method.present? || bold_labels
23
24
  end
24
25
 
25
26
  def html
26
- Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
27
- Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, caption: @caption, described_by: [error_id, hint_id, supplemental_id]).html do
27
+ Containers::FormGroup.new(@builder, @object_name, @attribute_name, classes: @form_group_classes).html do
28
+ Containers::Fieldset.new(@builder, @object_name, @attribute_name, **fieldset_options).html do
28
29
  safe_join([supplemental_content, hint_element, error_element, radios])
29
30
  end
30
31
  end
@@ -32,6 +33,14 @@ module GOVUKDesignSystemFormBuilder
32
33
 
33
34
  private
34
35
 
36
+ def fieldset_options
37
+ {
38
+ legend: @legend,
39
+ caption: @caption,
40
+ described_by: [error_id, hint_id, supplemental_id]
41
+ }
42
+ end
43
+
35
44
  def radios
36
45
  Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
37
46
  safe_join(collection)