govuk_design_system_formbuilder 0.7.9 → 0.7.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +52 -18
  3. data/lib/govuk_design_system_formbuilder.rb +19 -4
  4. data/lib/govuk_design_system_formbuilder/base.rb +54 -17
  5. data/lib/govuk_design_system_formbuilder/builder.rb +147 -93
  6. data/lib/govuk_design_system_formbuilder/containers/check_boxes_fieldset.rb +28 -0
  7. data/lib/govuk_design_system_formbuilder/containers/fieldset.rb +3 -9
  8. data/lib/govuk_design_system_formbuilder/containers/radio_buttons_fieldset.rb +29 -0
  9. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection.rb +62 -0
  10. data/lib/govuk_design_system_formbuilder/elements/check_boxes/collection_check_box.rb +21 -7
  11. data/lib/govuk_design_system_formbuilder/elements/check_boxes/fieldset_check_box.rb +75 -0
  12. data/lib/govuk_design_system_formbuilder/elements/check_boxes/hint.rb +9 -17
  13. data/lib/govuk_design_system_formbuilder/elements/check_boxes/label.rb +5 -4
  14. data/lib/govuk_design_system_formbuilder/elements/date.rb +18 -14
  15. data/lib/govuk_design_system_formbuilder/elements/error_message.rb +6 -4
  16. data/lib/govuk_design_system_formbuilder/elements/error_summary.rb +23 -8
  17. data/lib/govuk_design_system_formbuilder/elements/file.rb +40 -0
  18. data/lib/govuk_design_system_formbuilder/elements/hint.rb +1 -1
  19. data/lib/govuk_design_system_formbuilder/elements/input.rb +4 -12
  20. data/lib/govuk_design_system_formbuilder/elements/label.rb +16 -6
  21. data/lib/govuk_design_system_formbuilder/elements/radios/collection.rb +55 -0
  22. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio_button.rb +48 -0
  23. data/lib/govuk_design_system_formbuilder/elements/radios/{fieldset_radio.rb → fieldset_radio_button.rb} +17 -8
  24. data/lib/govuk_design_system_formbuilder/elements/select.rb +51 -0
  25. data/lib/govuk_design_system_formbuilder/elements/submit.rb +21 -13
  26. data/lib/govuk_design_system_formbuilder/elements/text_area.rb +4 -8
  27. data/lib/govuk_design_system_formbuilder/version.rb +1 -1
  28. metadata +32 -12
  29. data/lib/govuk_design_system_formbuilder/elements/radios/collection_radio.rb +0 -33
@@ -0,0 +1,40 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ class File < GOVUKDesignSystemFormBuilder::Base
4
+ def initialize(builder, object_name, attribute_name, hint_text:, label:, **extra_args)
5
+ super(builder, object_name, attribute_name)
6
+
7
+ @label = label
8
+ @hint_text = hint_text
9
+ @extra_args = extra_args
10
+ end
11
+
12
+ def html
13
+ Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
14
+ @builder.safe_join(
15
+ [
16
+ label_element.html,
17
+ hint_element.html,
18
+ error_element.html,
19
+ @builder.file_field(
20
+ @attribute_name,
21
+ id: field_id(link_errors: true),
22
+ class: file_classes,
23
+ aria: { describedby: described_by(hint_element.hint_id, error_element.error_id) },
24
+ **@extra_args
25
+ )
26
+ ]
27
+ )
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def file_classes
34
+ %w(govuk-file-upload).tap do |c|
35
+ c.push('govuk-file-upload--error') if has_errors?
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -11,7 +11,7 @@ module GOVUKDesignSystemFormBuilder
11
11
  end
12
12
 
13
13
  def html
14
- return nil unless @hint_text.present?
14
+ return nil if @hint_text.blank?
15
15
 
16
16
  @builder.tag.span(@hint_text, class: hint_classes, id: hint_id)
17
17
  end
@@ -12,10 +12,6 @@ module GOVUKDesignSystemFormBuilder
12
12
  end
13
13
 
14
14
  def html
15
- hint_element = Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text)
16
- label_element = Elements::Label.new(@builder, @object_name, @attribute_name, @label)
17
- error_element = Elements::ErrorMessage.new(@builder, @object_name, @attribute_name)
18
-
19
15
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
20
16
  @builder.safe_join(
21
17
  [
@@ -25,13 +21,9 @@ module GOVUKDesignSystemFormBuilder
25
21
  @builder.send(
26
22
  @builder_method,
27
23
  @attribute_name,
24
+ id: field_id(link_errors: true),
28
25
  class: input_classes,
29
- aria: {
30
- describedby: [
31
- hint_element.hint_id,
32
- error_element.error_id
33
- ].compact.join(' ').presence
34
- },
26
+ aria: { describedby: described_by(hint_element.hint_id, error_element.error_id) },
35
27
  **@extra_args
36
28
  )
37
29
  ]
@@ -49,7 +41,7 @@ module GOVUKDesignSystemFormBuilder
49
41
  end
50
42
 
51
43
  def width_classes
52
- return unless @width.present?
44
+ return if @width.blank?
53
45
 
54
46
  case @width
55
47
  # fixed (character) widths
@@ -68,7 +60,7 @@ module GOVUKDesignSystemFormBuilder
68
60
  when 'one-third' then 'govuk-!-width-one-third'
69
61
  when 'one-quarter' then 'govuk-!-width-one-quarter'
70
62
 
71
- else fail "invalid width #{@width}"
63
+ else fail(ArgumentError, "invalid width '#{@width}'")
72
64
  end
73
65
  end
74
66
  end
@@ -1,29 +1,39 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  class Label < GOVUKDesignSystemFormBuilder::Base
4
- def initialize(builder, object_name, attribute_name, text: nil, value: nil, size: nil, radio: false, checkbox: false)
4
+ def initialize(builder, object_name, attribute_name, text: nil, value: nil, size: nil, radio: false, checkbox: false, tag: nil)
5
5
  super(builder, object_name, attribute_name)
6
6
 
7
7
  @text = label_text(text)
8
- @value = value # used by attribute_descriptor
8
+ @value = value # used by field_id
9
9
  @size_class = label_size_class(size)
10
10
  @radio_class = radio_class(radio)
11
11
  @checkbox_class = checkbox_class(checkbox)
12
+ @tag = tag
12
13
  end
13
14
 
14
15
  def html
15
- return nil unless @text.present?
16
+ return nil if @text.blank?
16
17
 
18
+ if @tag.present?
19
+ @builder.content_tag(@tag, class: 'govuk-label-wrapper') { build_label }
20
+ else
21
+ build_label
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def build_label
17
28
  @builder.label(
18
29
  @attribute_name,
19
30
  @text,
20
31
  value: @value,
32
+ for: field_id,
21
33
  class: %w(govuk-label).push(@size_class, @weight_class, @radio_class, @checkbox_class).compact
22
34
  )
23
35
  end
24
36
 
25
- private
26
-
27
37
  def label_text(option_text)
28
38
  [option_text, @value, @attribute_name.capitalize].compact.first
29
39
  end
@@ -44,7 +54,7 @@ module GOVUKDesignSystemFormBuilder
44
54
  when 's' then "govuk-label--s"
45
55
  when nil then nil
46
56
  else
47
- fail "size must be either 'xl', 'l', 'm', 's' or nil"
57
+ fail "invalid size '#{size}', must be xl, l, m, s or nil"
48
58
  end
49
59
  end
50
60
  end
@@ -0,0 +1,55 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ module Radios
4
+ class Collection < GOVUKDesignSystemFormBuilder::Base
5
+ def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, hint_method:, hint_text:, legend:, inline:, small:, &block)
6
+ super(builder, object_name, attribute_name)
7
+
8
+ @collection = collection
9
+ @value_method = value_method
10
+ @text_method = text_method
11
+ @hint_method = hint_method
12
+ @inline = inline
13
+ @small = small
14
+ @legend = legend
15
+ @hint_text = hint_text
16
+ @block_content = @builder.capture { block.call } if block_given?
17
+ end
18
+
19
+ def html
20
+ Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
21
+ Containers::Fieldset.new(@builder, legend: @legend, described_by: [error_element.error_id, hint_element.hint_id]).html do
22
+ @builder.safe_join(
23
+ [
24
+ hint_element.html,
25
+ error_element.html,
26
+ @block_content,
27
+ Containers::Radios.new(@builder, inline: @inline, small: @small).html do
28
+ @builder.safe_join(build_collection)
29
+ end
30
+ ]
31
+ )
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def build_collection
39
+ @collection.map.with_index do |item, i|
40
+ Elements::Radios::CollectionRadioButton.new(
41
+ @builder,
42
+ @object_name,
43
+ @attribute_name,
44
+ item,
45
+ value_method: @value_method,
46
+ text_method: @text_method,
47
+ hint_method: @hint_method,
48
+ link_errors: has_errors? && i.zero?
49
+ ).html
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,48 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ module Radios
4
+ class CollectionRadioButton < Base
5
+ # @param link_errors [Boolean] used to control the id generated for radio buttons. The
6
+ # error summary requires that the id of the first radio is linked-to from the corresponding
7
+ # error message. As when the summary is built what happens later in the form is unknown, we
8
+ # need to control this to ensure the link is generated correctly
9
+ def initialize(builder, object_name, attribute_name, item, value_method:, text_method:, hint_method:, link_errors: false)
10
+ super(builder, object_name, attribute_name)
11
+ @item = item
12
+ @value = item.send(value_method)
13
+ @text = item.send(text_method)
14
+ @hint_text = item.send(hint_method) if hint_method.present?
15
+ @link_errors = link_errors
16
+ end
17
+
18
+ def html
19
+ @builder.content_tag('div', class: 'govuk-radios__item') do
20
+ @builder.safe_join(
21
+ [
22
+ @builder.radio_button(
23
+ @attribute_name,
24
+ @value,
25
+ id: field_id(link_errors: @link_errors),
26
+ aria: { describedby: hint_id },
27
+ class: %w(govuk-radios__input)
28
+ ),
29
+ label_element.html,
30
+ hint_element.html
31
+ ]
32
+ )
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def hint_element
39
+ @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text, @value, radio: true)
40
+ end
41
+
42
+ def label_element
43
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, text: @text, value: @value, radio: true)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,13 +1,14 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  module Radios
4
- class FieldsetRadio < Base
5
- def initialize(builder, object_name, attribute_name, value, label:, hint_text:, &block)
4
+ class FieldsetRadioButton < Base
5
+ def initialize(builder, object_name, attribute_name, value, label:, hint_text:, link_errors:, &block)
6
6
  super(builder, object_name, attribute_name)
7
7
 
8
- @value = value
9
- @label = label
10
- @hint_text = hint_text
8
+ @value = value
9
+ @label = label
10
+ @hint_text = hint_text
11
+ @link_errors = has_errors? && link_errors
11
12
 
12
13
  if block_given?
13
14
  @conditional_content = wrap_conditional(block)
@@ -20,8 +21,8 @@ module GOVUKDesignSystemFormBuilder
20
21
  @builder.safe_join(
21
22
  [
22
23
  input,
23
- Elements::Label.new(@builder, @object_name, @attribute_name, radio: true, value: @value, **@label).html,
24
- Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text, radio: true).html,
24
+ label_element.html,
25
+ hint_element.html,
25
26
  @conditional_content
26
27
  ]
27
28
  )
@@ -30,11 +31,19 @@ module GOVUKDesignSystemFormBuilder
30
31
 
31
32
  private
32
33
 
34
+ def label_element
35
+ @label_element ||= Elements::Label.new(@builder, @object_name, @attribute_name, radio: true, value: @value, **@label)
36
+ end
37
+
38
+ def hint_element
39
+ @hint_element ||= Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text, radio: true)
40
+ end
41
+
33
42
  def input
34
43
  @builder.radio_button(
35
44
  @attribute_name,
36
45
  @value,
37
- id: attribute_descriptor,
46
+ id: field_id(link_errors: @link_errors),
38
47
  aria: { describedby: hint_id },
39
48
  data: { 'aria-controls' => @conditional_id },
40
49
  class: %w(govuk-radios__input)
@@ -0,0 +1,51 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ class Select < GOVUKDesignSystemFormBuilder::Base
4
+ def initialize(builder, object_name, attribute_name, collection, value_method:, text_method:, options: {}, html_options: {}, hint_text:, label:, &block)
5
+ super(builder, object_name, attribute_name)
6
+
7
+ @collection = collection
8
+ @value_method = value_method
9
+ @text_method = text_method
10
+ @options = options
11
+ @html_options = html_options
12
+ @label = label
13
+ @hint_text = hint_text
14
+ @block_content = @builder.capture { block.call } if block_given?
15
+ end
16
+
17
+ def html
18
+ Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
19
+ @builder.safe_join([
20
+ label_element.html,
21
+ hint_element.html,
22
+ error_element.html,
23
+ @block_content,
24
+ @builder.collection_select(
25
+ @attribute_name,
26
+ @collection,
27
+ @value_method,
28
+ @text_method,
29
+ @options,
30
+ build_html_options(hint_element, error_element)
31
+ )
32
+ ])
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def build_html_options(hint_element, error_element)
39
+ @html_options.deep_merge(
40
+ id: field_id(link_errors: true),
41
+ class: select_classes,
42
+ aria: { describedby: described_by(hint_element.hint_id, error_element.error_id) }
43
+ )
44
+ end
45
+
46
+ def select_classes
47
+ %w(govuk-select)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -16,7 +16,12 @@ module GOVUKDesignSystemFormBuilder
16
16
  def html
17
17
  @builder.content_tag('div', class: %w(govuk-form-group)) do
18
18
  @builder.safe_join([
19
- @builder.submit(@text, class: submit_button_classes(@block_content.present?), **extra_args),
19
+ @builder.submit(@text, class: %w(govuk-button).push(
20
+ warning_class,
21
+ secondary_class,
22
+ padding_class(@block_content.present?)
23
+ ),
24
+ **extra_args),
20
25
  @block_content
21
26
  ])
22
27
  end
@@ -24,22 +29,25 @@ module GOVUKDesignSystemFormBuilder
24
29
 
25
30
  private
26
31
 
27
- def submit_button_classes(content_present)
28
- %w(govuk-button).tap do |classes|
29
- classes.push('govuk-button--warning') if @warning
30
- classes.push('govuk-button--secondary') if @secondary
32
+ def warning_class
33
+ 'govuk-button--warning' if @warning
34
+ end
31
35
 
32
- # NOTE only this input will receive a right margin, block
33
- # contents must be addressed individually
34
- classes.push('govuk-!-margin-right-1') if content_present
35
- end
36
+ def secondary_class
37
+ 'govuk-button--secondary' if @secondary
38
+ end
39
+
40
+ def padding_class(content_present)
41
+ 'govuk-!-margin-right-1' if content_present
36
42
  end
37
43
 
38
44
  def extra_args
39
- {}.tap do |ea|
40
- ea[:data] = { 'prevent-double-click' => @prevent_double_click } if @prevent_double_click
41
- ea[:formnovalidate] = !@validate
42
- end
45
+ {
46
+ formnovalidate: !@validate,
47
+ data: {
48
+ 'prevent-double-click' => @prevent_double_click
49
+ }.select { |_k, v| v.present? }
50
+ }
43
51
  end
44
52
  end
45
53
  end
@@ -13,24 +13,20 @@ module GOVUKDesignSystemFormBuilder
13
13
  end
14
14
 
15
15
  def html
16
- hint_element = Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text)
17
- label_element = Elements::Label.new(@builder, @object_name, @attribute_name, @label)
18
- error_element = Elements::ErrorMessage.new(@builder, @object_name, @attribute_name)
19
-
20
16
  Containers::CharacterCount.new(@builder, max_words: @max_words, max_chars: @max_chars, threshold: @threshold).html do
21
17
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
22
18
  @builder.safe_join(
23
19
  [
24
- label_element.html,
25
- hint_element.html,
26
- error_element.html,
20
+ [label_element, hint_element, error_element].map(&:html),
27
21
  @builder.text_area(
28
22
  @attribute_name,
23
+ id: field_id(link_errors: true),
29
24
  class: govuk_textarea_classes,
25
+ aria: { describedby: described_by(hint_element.hint_id, error_element.error_id) },
30
26
  **@extra_args.merge(rows: @rows)
31
27
  ),
32
28
  character_count_info
33
- ]
29
+ ].flatten.compact
34
30
  )
35
31
  end
36
32
  end
@@ -1,3 +1,3 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
- VERSION = '0.7.9'.freeze
2
+ VERSION = '0.7.10'.freeze
3
3
  end