govuk_design_system_formbuilder 1.2.4 → 2.0.0b2

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 (43) 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 +201 -78
  6. data/lib/govuk_design_system_formbuilder/containers/character_count.rb +2 -2
  7. data/lib/govuk_design_system_formbuilder/containers/check_boxes.rb +13 -12
  8. data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +4 -3
  9. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +12 -62
  10. data/lib/govuk_design_system_formbuilder/containers/form_group.rb +19 -10
  11. data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +4 -3
  12. data/lib/govuk_design_system_formbuilder/containers/radios.rb +17 -13
  13. data/lib/govuk_design_system_formbuilder/containers/supplemental.rb +3 -1
  14. data/lib/govuk_design_system_formbuilder/elements/caption.rb +14 -7
  15. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +12 -11
  16. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +9 -7
  17. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +19 -15
  18. data/lib/govuk_design_system_formbuilder/elements/date.rb +18 -17
  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 +37 -10
  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 +28 -22
  30. data/lib/govuk_design_system_formbuilder/elements/legend.rb +87 -0
  31. data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +14 -13
  32. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +13 -7
  33. data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +15 -7
  34. data/lib/govuk_design_system_formbuilder/elements/select.rb +18 -17
  35. data/lib/govuk_design_system_formbuilder/elements/submit.rb +9 -4
  36. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +10 -9
  37. data/lib/govuk_design_system_formbuilder/traits/caption.rb +1 -9
  38. data/lib/govuk_design_system_formbuilder/traits/collection_item.rb +1 -1
  39. data/lib/govuk_design_system_formbuilder/traits/conditional.rb +1 -1
  40. data/lib/govuk_design_system_formbuilder/traits/hint.rb +15 -2
  41. data/lib/govuk_design_system_formbuilder/traits/input.rb +4 -3
  42. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  43. metadata +12 -11
@@ -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
@@ -6,27 +6,29 @@ module GOVUKDesignSystemFormBuilder
6
6
  include Traits::Caption
7
7
  include Traits::Localisation
8
8
 
9
- def initialize(builder, object_name, attribute_name, text: nil, value: nil, size: nil, hidden: false, radio: false, checkbox: false, tag: nil, link_errors: true, content: nil, caption: nil)
9
+ def initialize(builder, object_name, attribute_name, text: nil, value: nil, size: nil, hidden: false, radio: false, checkbox: false, tag: nil, link_errors: true, content: nil, caption: nil, **kwargs)
10
10
  super(builder, object_name, attribute_name)
11
11
 
12
+ @value = value # used by field_id
13
+ @tag = tag
14
+ @radio = radio
15
+ @checkbox = checkbox
16
+ @link_errors = link_errors
17
+ @html_attributes = kwargs
18
+
12
19
  # content is passed in directly via a proc and overrides
13
20
  # the other display options
14
21
  if content
15
- @content = content.call
22
+ @content = capture { content.call }
16
23
  else
17
- @value = value # used by field_id
18
- @text = label_text(text, hidden)
19
- @size_class = label_size_class(size)
20
- @radio = radio
21
- @checkbox = checkbox
22
- @tag = tag
23
- @link_errors = link_errors
24
- @caption = caption
24
+ @text = retrieve_text(text, hidden)
25
+ @size_class = size_class(size)
26
+ @caption = caption
25
27
  end
26
28
  end
27
29
 
28
30
  def html
29
- return nil if [@content, @text].all?(&:blank?)
31
+ return nil unless active?
30
32
 
31
33
  if @tag.present?
32
34
  content_tag(@tag, class: %(#{brand}-label-wrapper)) { label }
@@ -35,25 +37,29 @@ module GOVUKDesignSystemFormBuilder
35
37
  end
36
38
  end
37
39
 
40
+ def active?
41
+ [@content, @text].any?(&:present?)
42
+ end
43
+
38
44
  private
39
45
 
40
46
  def label
41
- @builder.label(@attribute_name, **label_options) do
47
+ @builder.label(@attribute_name, **options, **@html_attributes) do
42
48
  @content || safe_join([caption, @text])
43
49
  end
44
50
  end
45
51
 
46
- def label_text(option_text, hidden)
47
- text = [option_text, localised_text(:label), @attribute_name.capitalize].compact.first.to_s
52
+ def retrieve_text(option_text, hidden)
53
+ text = [option_text, localised_text(:label), @attribute_name.capitalize].compact.first
48
54
 
49
55
  if hidden
50
- tag.span(text, class: %w(visually-hidden).prefix(brand))
56
+ tag.span(text, class: %(#{brand}-visually-hidden))
51
57
  else
52
58
  text
53
59
  end
54
60
  end
55
61
 
56
- def label_options
62
+ def options
57
63
  {
58
64
  value: @value,
59
65
  for: field_id(link_errors: @link_errors),
@@ -77,13 +83,13 @@ module GOVUKDesignSystemFormBuilder
77
83
  %(#{brand}-checkboxes__label)
78
84
  end
79
85
 
80
- def label_size_class(size)
86
+ def size_class(size)
81
87
  case size
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
88
+ when 'xl' then %(#{brand}-label--xl)
89
+ when 'l' then %(#{brand}-label--l)
90
+ when 'm' then %(#{brand}-label--m)
91
+ when 's' then %(#{brand}-label--s)
92
+ when nil then nil
87
93
  else
88
94
  fail "invalid size '#{size}', must be xl, l, m, s or nil"
89
95
  end
@@ -0,0 +1,87 @@
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:, **kwargs)
8
+ super(builder, object_name, attribute_name)
9
+
10
+ @html_attributes = kwargs
11
+
12
+ case legend
13
+ when NilClass
14
+ @active = false
15
+ when Proc
16
+ @raw = capture { legend.call }
17
+ when Hash
18
+ defaults.merge(legend).tap do |l|
19
+ @text = retrieve_text(l.dig(:text))
20
+ @hidden = l.dig(:hidden)
21
+ @tag = l.dig(:tag)
22
+ @size = l.dig(:size)
23
+ @caption = caption
24
+ end
25
+ else
26
+ fail(ArgumentError, %(legend must be a Proc or Hash))
27
+ end
28
+ end
29
+
30
+ def html
31
+ @raw || content
32
+ end
33
+
34
+ private
35
+
36
+ def active?
37
+ [@text, @raw].any?(&:present?)
38
+ end
39
+
40
+ def content
41
+ return nil unless active?
42
+
43
+ tag.legend(class: classes, **@html_attributes) do
44
+ content_tag(@tag, class: heading_classes) do
45
+ safe_join([caption_element, @text])
46
+ end
47
+ end
48
+ end
49
+
50
+ def retrieve_text(supplied_text)
51
+ [supplied_text, localised_text(:legend), @attribute_name&.capitalize].compact.first
52
+ end
53
+
54
+ def classes
55
+ [%(#{brand}-fieldset__legend), size_class, visually_hidden_class].compact
56
+ end
57
+
58
+ def size_class
59
+ case @size
60
+ when 'xl' then %(#{brand}-fieldset__legend--xl)
61
+ when 'l' then %(#{brand}-fieldset__legend--l)
62
+ when 'm' then %(#{brand}-fieldset__legend--m)
63
+ when 's' then %(#{brand}-fieldset__legend--s)
64
+ else
65
+ fail "invalid size '#{@size}', must be xl, l, m or s"
66
+ end
67
+ end
68
+
69
+ def visually_hidden_class
70
+ %(#{brand}-visually-hidden) if @hidden
71
+ end
72
+
73
+ def heading_classes
74
+ %(#{brand}-fieldset__heading)
75
+ end
76
+
77
+ def defaults
78
+ {
79
+ hidden: false,
80
+ text: nil,
81
+ tag: config.default_legend_tag,
82
+ size: config.default_legend_size
83
+ }
84
+ end
85
+ end
86
+ end
87
+ end
@@ -6,24 +6,25 @@ 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:, legend:, caption:, inline:, small:, bold_labels:, classes:, form_group:, &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 = hint
21
+ @classes = classes
22
+ @form_group = form_group
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::FormGroup.new(@builder, @object_name, @attribute_name, **@form_group).html do
27
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
@@ -2,8 +2,6 @@ module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Radios
4
4
  class CollectionRadioButton < Base
5
- using PrefixableArray
6
-
7
5
  include Traits::Hint
8
6
  include Traits::CollectionItem
9
7
 
@@ -23,7 +21,7 @@ module GOVUKDesignSystemFormBuilder
23
21
  end
24
22
 
25
23
  def html
26
- content_tag('div', class: %(#{brand}-radios__item)) do
24
+ tag.div(class: %(#{brand}-radios__item)) do
27
25
  safe_join([radio, label_element, hint_element])
28
26
  end
29
27
  end
@@ -31,19 +29,27 @@ module GOVUKDesignSystemFormBuilder
31
29
  private
32
30
 
33
31
  def radio
34
- @builder.radio_button(@attribute_name, @value, **radio_options)
32
+ @builder.radio_button(@attribute_name, @value, **options)
35
33
  end
36
34
 
37
- def radio_options
35
+ def options
38
36
  {
39
37
  id: field_id(link_errors: @link_errors),
40
38
  aria: { describedby: hint_id },
41
- class: %w(radios__input).prefix(brand)
39
+ class: %(#{brand}-radios__input)
42
40
  }
43
41
  end
44
42
 
45
43
  def hint_element
46
- @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text, @value, radio: true)
44
+ @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, **hint_options, **hint_content)
45
+ end
46
+
47
+ def hint_content
48
+ { text: @hint_text }
49
+ end
50
+
51
+ def hint_options
52
+ { value: @value, radio: true }
47
53
  end
48
54
 
49
55
  def label_element
@@ -8,12 +8,12 @@ module GOVUKDesignSystemFormBuilder
8
8
  include Traits::Hint
9
9
  include Traits::Conditional
10
10
 
11
- def initialize(builder, object_name, attribute_name, value, label:, hint_text:, link_errors:, &block)
11
+ def initialize(builder, object_name, attribute_name, value, label:, hint:, link_errors:, &block)
12
12
  super(builder, object_name, attribute_name)
13
13
 
14
14
  @value = value
15
15
  @label = label
16
- @hint_text = hint_text
16
+ @hint = hint
17
17
  @link_errors = has_errors? && link_errors
18
18
 
19
19
  if block_given?
@@ -29,28 +29,36 @@ module GOVUKDesignSystemFormBuilder
29
29
  private
30
30
 
31
31
  def radio
32
- content_tag('div', class: %(#{brand}-radios__item)) do
32
+ tag.div(class: %(#{brand}-radios__item)) do
33
33
  safe_join([input, label_element, hint_element])
34
34
  end
35
35
  end
36
36
 
37
+ def radio_options
38
+ { radio: true }
39
+ end
40
+
37
41
  def label_element
38
42
  @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, **label_content, **label_options)
39
43
  end
40
44
 
41
45
  def label_options
42
- { radio: true, value: @value, link_errors: @link_errors }
46
+ { value: @value, link_errors: @link_errors }.merge(radio_options)
43
47
  end
44
48
 
45
49
  def hint_element
46
- @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text, @value, radio: true)
50
+ @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, **hint_options, **hint_content)
51
+ end
52
+
53
+ def hint_options
54
+ { value: @value }.merge(radio_options)
47
55
  end
48
56
 
49
57
  def input
50
- @builder.radio_button(@attribute_name, @value, **input_options)
58
+ @builder.radio_button(@attribute_name, @value, **options)
51
59
  end
52
60
 
53
- def input_options
61
+ def options
54
62
  {
55
63
  id: field_id(link_errors: @link_errors),
56
64
  aria: { describedby: hint_id },
@@ -6,21 +6,22 @@ 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:, options: {}, html_options: {}, hint_text:, label:, caption:, &block)
9
+ def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, options: {}, html_options: {}, hint:, label:, caption:, form_group:, &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
- @options = options
16
- @html_options = html_options
17
- @label = label
18
- @caption = caption
19
- @hint_text = hint_text
12
+ @collection = collection
13
+ @value_method = value_method
14
+ @text_method = text_method
15
+ @options = options
16
+ @html_options = html_options
17
+ @label = label
18
+ @caption = caption
19
+ @hint = hint
20
+ @form_group = form_group
20
21
  end
21
22
 
22
23
  def html
23
- Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
24
+ Containers::FormGroup.new(@builder, @object_name, @attribute_name, **@form_group).html do
24
25
  safe_join([label_element, supplemental_content, hint_element, error_element, select])
25
26
  end
26
27
  end
@@ -28,26 +29,26 @@ module GOVUKDesignSystemFormBuilder
28
29
  private
29
30
 
30
31
  def select
31
- @builder.collection_select(@attribute_name, @collection, @value_method, @text_method, @options, **select_options)
32
+ @builder.collection_select(@attribute_name, @collection, @value_method, @text_method, @options, **options)
32
33
  end
33
34
 
34
- def select_options
35
+ def options
35
36
  @html_options.deep_merge(
36
37
  id: field_id(link_errors: true),
37
- class: select_classes,
38
+ class: classes,
38
39
  aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
39
40
  )
40
41
  end
41
42
 
42
- def select_classes
43
- [%(#{brand}-select), select_error_class, select_custom_classes].flatten.compact
43
+ def classes
44
+ [%(#{brand}-select), error_class, custom_classes].flatten.compact
44
45
  end
45
46
 
46
- def select_error_class
47
+ def error_class
47
48
  %(#{brand}-select--error) if has_errors?
48
49
  end
49
50
 
50
- def select_custom_classes
51
+ def custom_classes
51
52
  @html_options.dig(:class)
52
53
  end
53
54
  end
@@ -24,17 +24,18 @@ module GOVUKDesignSystemFormBuilder
24
24
  private
25
25
 
26
26
  def submit
27
- @builder.submit(@text, class: submit_classes, **submit_options)
27
+ @builder.submit(@text, class: classes, **options)
28
28
  end
29
29
 
30
- def submit_classes
30
+ def classes
31
31
  %w(button)
32
32
  .prefix(brand)
33
- .push(warning_class, secondary_class, disabled_class, padding_class, @classes)
33
+ .push(warning_class, secondary_class, disabled_class, padding_class, custom_classes)
34
+ .flatten
34
35
  .compact
35
36
  end
36
37
 
37
- def submit_options
38
+ def options
38
39
  {
39
40
  formnovalidate: !@validate,
40
41
  disabled: @disabled,
@@ -60,6 +61,10 @@ module GOVUKDesignSystemFormBuilder
60
61
  def disabled_class
61
62
  %(#{brand}-button--disabled) if @disabled
62
63
  end
64
+
65
+ def custom_classes
66
+ Array.wrap(@classes)
67
+ end
63
68
  end
64
69
  end
65
70
  end