govuk_design_system_formbuilder 1.2.0 → 1.2.5

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/govuk_design_system_formbuilder.rb +4 -0
  3. data/lib/govuk_design_system_formbuilder/base.rb +5 -0
  4. data/lib/govuk_design_system_formbuilder/builder.rb +52 -33
  5. data/lib/govuk_design_system_formbuilder/containers/character_count.rb +8 -7
  6. data/lib/govuk_design_system_formbuilder/containers/check_boxes.rb +18 -10
  7. data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +27 -18
  8. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +15 -55
  9. data/lib/govuk_design_system_formbuilder/containers/form_group.rb +18 -10
  10. data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +28 -19
  11. data/lib/govuk_design_system_formbuilder/containers/radios.rb +22 -11
  12. data/lib/govuk_design_system_formbuilder/containers/supplemental.rb +3 -3
  13. data/lib/govuk_design_system_formbuilder/elements/caption.rb +8 -6
  14. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +29 -23
  15. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +17 -15
  16. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +28 -32
  17. data/lib/govuk_design_system_formbuilder/elements/date.rb +55 -51
  18. data/lib/govuk_design_system_formbuilder/elements/error_message.rb +7 -6
  19. data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +24 -27
  20. data/lib/govuk_design_system_formbuilder/elements/file.rb +21 -22
  21. data/lib/govuk_design_system_formbuilder/elements/hint.rb +13 -16
  22. data/lib/govuk_design_system_formbuilder/elements/inputs/email.rb +2 -0
  23. data/lib/govuk_design_system_formbuilder/elements/label.rb +40 -29
  24. data/lib/govuk_design_system_formbuilder/elements/legend.rb +79 -0
  25. data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +46 -36
  26. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +24 -14
  27. data/lib/govuk_design_system_formbuilder/elements/radios/fieldset_radio_button.rb +18 -19
  28. data/lib/govuk_design_system_formbuilder/elements/select.rb +28 -34
  29. data/lib/govuk_design_system_formbuilder/elements/submit.rb +34 -25
  30. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +39 -40
  31. data/lib/govuk_design_system_formbuilder/traits/caption.rb +5 -6
  32. data/lib/govuk_design_system_formbuilder/traits/input.rb +21 -29
  33. data/lib/govuk_design_system_formbuilder/traits/label.rb +2 -2
  34. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  35. metadata +16 -15
@@ -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 = 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
+ content_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,56 +6,66 @@ 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
28
- safe_join(
29
- [
30
- supplemental_content.html,
31
- hint_element.html,
32
- error_element.html,
33
- Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
34
- safe_join(build_collection)
35
- end
36
- ]
37
- )
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
29
+ safe_join([supplemental_content, hint_element, error_element, radios])
38
30
  end
39
31
  end
40
32
  end
41
33
 
42
34
  private
43
35
 
44
- def build_collection
36
+ def fieldset_options
37
+ {
38
+ legend: @legend,
39
+ caption: @caption,
40
+ described_by: [error_id, hint_id, supplemental_id]
41
+ }
42
+ end
43
+
44
+ def radios
45
+ Containers::Radios.new(@builder, inline: @inline, small: @small, classes: @classes).html do
46
+ safe_join(collection)
47
+ end
48
+ end
49
+
50
+ def collection
45
51
  @collection.map.with_index do |item, i|
46
- Elements::Radios::CollectionRadioButton.new(
47
- @builder,
48
- @object_name,
49
- @attribute_name,
50
- item,
51
- value_method: @value_method,
52
- text_method: @text_method,
53
- hint_method: @hint_method,
54
- link_errors: has_errors? && i.zero?,
55
- bold_labels: @bold_labels
56
- ).html
52
+ Elements::Radios::CollectionRadioButton.new(@builder, @object_name, @attribute_name, item, **collection_options(i)).html
57
53
  end
58
54
  end
55
+
56
+ def collection_options(index)
57
+ {
58
+ value_method: @value_method,
59
+ text_method: @text_method,
60
+ hint_method: @hint_method,
61
+ link_errors: link_errors?(index),
62
+ bold_labels: @bold_labels
63
+ }
64
+ end
65
+
66
+ def link_errors?(index)
67
+ has_errors? && index.zero?
68
+ end
59
69
  end
60
70
  end
61
71
  end
@@ -24,30 +24,40 @@ module GOVUKDesignSystemFormBuilder
24
24
 
25
25
  def html
26
26
  content_tag('div', class: %(#{brand}-radios__item)) do
27
- safe_join(
28
- [
29
- @builder.radio_button(
30
- @attribute_name,
31
- @value,
32
- id: field_id(link_errors: @link_errors),
33
- aria: { describedby: hint_id },
34
- class: %w(radios__input).prefix(brand)
35
- ),
36
- label_element.html,
37
- hint_element.html
38
- ]
39
- )
27
+ safe_join([radio, label_element, hint_element])
40
28
  end
41
29
  end
42
30
 
43
31
  private
44
32
 
33
+ def radio
34
+ @builder.radio_button(@attribute_name, @value, **options)
35
+ end
36
+
37
+ def options
38
+ {
39
+ id: field_id(link_errors: @link_errors),
40
+ aria: { describedby: hint_id },
41
+ class: %w(radios__input).prefix(brand)
42
+ }
43
+ end
44
+
45
45
  def hint_element
46
46
  @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text, @value, radio: true)
47
47
  end
48
48
 
49
49
  def label_element
50
- @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, text: @label_text, value: @value, radio: true, size: label_size, link_errors: @link_errors)
50
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, **label_options)
51
+ end
52
+
53
+ def label_options
54
+ {
55
+ text: @label_text,
56
+ value: @value,
57
+ radio: true,
58
+ size: label_size,
59
+ link_errors: @link_errors
60
+ }
51
61
  end
52
62
 
53
63
  def label_size
@@ -23,26 +23,23 @@ module GOVUKDesignSystemFormBuilder
23
23
  end
24
24
 
25
25
  def html
26
- safe_join(
27
- [
28
- content_tag('div', class: %(#{brand}-radios__item)) do
29
- safe_join(
30
- [
31
- input,
32
- label_element.html,
33
- hint_element.html,
34
- ]
35
- )
36
- end,
37
- @conditional_content
38
- ]
39
- )
26
+ safe_join([radio, @conditional_content])
40
27
  end
41
28
 
42
29
  private
43
30
 
31
+ def radio
32
+ content_tag('div', class: %(#{brand}-radios__item)) do
33
+ safe_join([input, label_element, hint_element])
34
+ end
35
+ end
36
+
44
37
  def label_element
45
- @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, radio: true, value: @value, link_errors: @link_errors, **label_args)
38
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, **label_content, **label_options)
39
+ end
40
+
41
+ def label_options
42
+ { radio: true, value: @value, link_errors: @link_errors }
46
43
  end
47
44
 
48
45
  def hint_element
@@ -50,14 +47,16 @@ module GOVUKDesignSystemFormBuilder
50
47
  end
51
48
 
52
49
  def input
53
- @builder.radio_button(
54
- @attribute_name,
55
- @value,
50
+ @builder.radio_button(@attribute_name, @value, **options)
51
+ end
52
+
53
+ def options
54
+ {
56
55
  id: field_id(link_errors: @link_errors),
57
56
  aria: { describedby: hint_id },
58
57
  data: { 'aria-controls' => @conditional_id },
59
58
  class: %w(radios__input).prefix(brand)
60
- )
59
+ }
61
60
  end
62
61
 
63
62
  def conditional_classes
@@ -1,61 +1,55 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  class Select < Base
4
- using PrefixableArray
5
-
6
4
  include Traits::Error
7
5
  include Traits::Label
8
6
  include Traits::Hint
9
7
  include Traits::Supplemental
10
8
 
11
- 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_text:, label:, caption:, form_group_classes:, &block)
12
10
  super(builder, object_name, attribute_name, &block)
13
11
 
14
- @collection = collection
15
- @value_method = value_method
16
- @text_method = text_method
17
- @options = options
18
- @html_options = html_options
19
- @label = label
20
- @caption = caption
21
- @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_text = hint_text
20
+ @form_group_classes = form_group_classes
22
21
  end
23
22
 
24
23
  def html
25
- Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
26
- safe_join(
27
- [
28
- label_element.html,
29
- supplemental_content.html,
30
- hint_element.html,
31
- error_element.html,
32
- @builder.collection_select(
33
- @attribute_name,
34
- @collection,
35
- @value_method,
36
- @text_method,
37
- @options,
38
- build_html_options
39
- )
40
- ]
41
- )
24
+ Containers::FormGroup.new(@builder, @object_name, @attribute_name, classes: @form_group_classes).html do
25
+ safe_join([label_element, supplemental_content, hint_element, error_element, select])
42
26
  end
43
27
  end
44
28
 
45
29
  private
46
30
 
47
- def build_html_options
31
+ def select
32
+ @builder.collection_select(@attribute_name, @collection, @value_method, @text_method, @options, **options)
33
+ end
34
+
35
+ def options
48
36
  @html_options.deep_merge(
49
37
  id: field_id(link_errors: true),
50
- class: select_classes,
38
+ class: classes,
51
39
  aria: { describedby: described_by(hint_id, error_id, supplemental_id) }
52
40
  )
53
41
  end
54
42
 
55
- def select_classes
56
- %w(select).prefix(brand).tap do |classes|
57
- classes.push(%(#{brand}-select--error)) if has_errors?
58
- end
43
+ def classes
44
+ [%(#{brand}-select), error_class, custom_classes].flatten.compact
45
+ end
46
+
47
+ def error_class
48
+ %(#{brand}-select--error) if has_errors?
49
+ end
50
+
51
+ def custom_classes
52
+ @html_options.dig(:class)
59
53
  end
60
54
  end
61
55
  end
@@ -3,7 +3,7 @@ module GOVUKDesignSystemFormBuilder
3
3
  class Submit < Base
4
4
  using PrefixableArray
5
5
 
6
- def initialize(builder, text, warning:, secondary:, classes:, prevent_double_click:, validate:, &block)
6
+ def initialize(builder, text, warning:, secondary:, classes:, prevent_double_click:, validate:, disabled:, &block)
7
7
  fail ArgumentError, 'buttons can be warning or secondary' if warning && secondary
8
8
 
9
9
  @builder = builder
@@ -13,29 +13,39 @@ module GOVUKDesignSystemFormBuilder
13
13
  @secondary = secondary
14
14
  @classes = classes
15
15
  @validate = validate
16
+ @disabled = disabled
16
17
  @block_content = capture { block.call } if block_given?
17
18
  end
18
19
 
19
20
  def html
20
- safe_join(
21
- [
22
- @builder.submit(
23
- @text,
24
- class: %w(button).prefix(brand).push(
25
- warning_class,
26
- secondary_class,
27
- @classes,
28
- padding_class(@block_content.present?)
29
- ).compact,
30
- **extra_args
31
- ),
32
- @block_content
33
- ]
34
- )
21
+ safe_join([submit, @block_content])
35
22
  end
36
23
 
37
24
  private
38
25
 
26
+ def submit
27
+ @builder.submit(@text, class: classes, **options)
28
+ end
29
+
30
+ def classes
31
+ %w(button)
32
+ .prefix(brand)
33
+ .push(warning_class, secondary_class, disabled_class, padding_class, custom_classes)
34
+ .flatten
35
+ .compact
36
+ end
37
+
38
+ def options
39
+ {
40
+ formnovalidate: !@validate,
41
+ disabled: @disabled,
42
+ data: {
43
+ module: %(#{brand}-button),
44
+ 'prevent-double-click': @prevent_double_click
45
+ }.select { |_k, v| v.present? }
46
+ }
47
+ end
48
+
39
49
  def warning_class
40
50
  %(#{brand}-button--warning) if @warning
41
51
  end
@@ -44,17 +54,16 @@ module GOVUKDesignSystemFormBuilder
44
54
  %(#{brand}-button--secondary) if @secondary
45
55
  end
46
56
 
47
- def padding_class(content_present)
48
- %(#{brand}-!-margin-right-1) if content_present
57
+ def padding_class
58
+ %(#{brand}-!-margin-right-1) if @block_content
49
59
  end
50
60
 
51
- def extra_args
52
- {
53
- formnovalidate: !@validate,
54
- data: {
55
- module: %(#{brand}-button), 'prevent-double-click' => @prevent_double_click
56
- }.select { |_k, v| v.present? }
57
- }
61
+ def disabled_class
62
+ %(#{brand}-button--disabled) if @disabled
63
+ end
64
+
65
+ def custom_classes
66
+ Array.wrap(@classes)
58
67
  end
59
68
  end
60
69
  end