govuk_design_system_formbuilder 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5dccd0fa57d48d4d0198307c0c4e11ac03dba8ffacd9bcf7850ba509477e4a82
4
- data.tar.gz: f3f197d18cc7fb186cf319da8b90f16d9bef48bc0e3c6493857633105872b599
3
+ metadata.gz: 3c247c34794b087d27148758c3f540b38e241afbf42d7a4692b0043bd950518d
4
+ data.tar.gz: 8644e39ebe2339b34b41feea5c73f3de67888d4b89dc847a3ba332233cf163b2
5
5
  SHA512:
6
- metadata.gz: dd17c106ef4052149c832e5e8428b7beeddb56cdef0ec4861036242069021d4a5122da8c817e19902c757513a9bc23bf47b4809c63fbc2f20ca19eb983921ee5
7
- data.tar.gz: c3ee032aa1925b929abcf0a9d400f1a1404bb5a56b8290ae1f66d475018841a88bb4c504fddfa41ae4baf8d1a7094eb645b67d6b2ffbf935d726a023c42bd2a0
6
+ metadata.gz: 770f26c8ccddb0704b9e7f366cb122bc670ceec87e7e556d8a38dc9a55b1340c92aa6558dddb6224133efed153f72da1c659c0570994c6975e45d730042cd916
7
+ data.tar.gz: 498191263c697030b558bf5cfdec236c68ff4f77d66ee0285423489b123e3720e4f83c1eab87f8f124a9c9adf2489cbf524d6d132bc0e1e3701b9b90f80d3a39
data/README.md CHANGED
@@ -47,6 +47,15 @@ Now we can get started! 🎉
47
47
 
48
48
  = f.govuk_number_field :age, label: { text: 'Age' }
49
49
 
50
+ = f.govuk_collection_select :department_id,
51
+ @departments,
52
+ :id,
53
+ :name,
54
+ :description,
55
+ label: { text: 'Which department do you work for?' },
56
+ hint_text: "If you don't know ask your manager" }
57
+
58
+
50
59
  = f.submit 'Away we go!'
51
60
  ```
52
61
 
@@ -13,17 +13,21 @@ module GOVUKDesignSystemFormBuilder
13
13
  def hint_id
14
14
  return nil unless @hint_text.present?
15
15
 
16
- [@object_name, @attribute_name, @value, 'hint'].compact.join('-').parameterize
16
+ build_id('hint')
17
17
  end
18
18
 
19
19
  def error_id
20
20
  return nil unless has_errors?
21
21
 
22
- [@object_name, @attribute_name, 'error'].compact.join('-').parameterize
22
+ build_id('error')
23
23
  end
24
24
 
25
25
  def conditional_id
26
- [@object_name, @attribute_name, @value, 'conditional'].compact.join('-').parameterize
26
+ build_id('conditional')
27
+ end
28
+
29
+ def attribute_descriptor
30
+ build_id(nil, '_', '-')
27
31
  end
28
32
 
29
33
  def has_errors?
@@ -31,10 +35,6 @@ module GOVUKDesignSystemFormBuilder
31
35
  @builder.object.errors.messages.keys.include?(@attribute_name)
32
36
  end
33
37
 
34
- def attribute_descriptor
35
- [@object_name, @attribute_name, @value].compact.join('_').parameterize
36
- end
37
-
38
38
  def attribute_identifier
39
39
  "%<object_name>s[%<attribute_name>s]" % {
40
40
  object_name: @object_name,
@@ -46,7 +46,23 @@ module GOVUKDesignSystemFormBuilder
46
46
  conditional = @builder.content_tag('div', class: conditional_classes, id: conditional_id) do
47
47
  @builder.capture { block.call }
48
48
  end
49
+
49
50
  return conditional, conditional_id
50
51
  end
52
+
53
+ private
54
+
55
+ def build_id(id_type, delimiter = '-', replace = '_', override_attribute_name: nil)
56
+ [
57
+ @object_name,
58
+ (override_attribute_name || @attribute_name),
59
+ @value,
60
+ id_type
61
+ ]
62
+ .compact
63
+ .join(delimiter)
64
+ .parameterize
65
+ .tr(replace, delimiter)
66
+ end
51
67
  end
52
68
  end
@@ -4,6 +4,8 @@ module GOVUKDesignSystemFormBuilder
4
4
  #
5
5
  # @param attribute_name [Symbol] The name of the attribute
6
6
  # @param hint_text [String] The content of the hint. No hint will be injected if left +nil+
7
+ # @param width [Integer,String] sets the width of the input, can be +2+, +3+ +4+, +5+, +10+ or +20+ characters
8
+ # or +one-quarter+, +one-third+, +one-half+, +two-thirds+ or +full+ width of the container
7
9
  # @param [Hash] label configures the associated label
8
10
  # @option label text [String] the label text
9
11
  # @option label size [String] the size of the label font, can be +large+, +medium+, +regular+ or +small+
@@ -18,14 +20,16 @@ module GOVUKDesignSystemFormBuilder
18
20
  # hint_text: 'It says it on your birth certificate',
19
21
  # required: true,
20
22
  # placeholder: 'Ralph Wiggum'
21
- def govuk_text_field(attribute_name, hint_text: nil, label: {}, **args)
22
- Elements::Input.new(self, object_name, attribute_name, attribute_type: :text, hint_text: hint_text, label: label, **args).html
23
+ def govuk_text_field(attribute_name, hint_text: nil, label: {}, width: 'full', **args)
24
+ Elements::Input.new(self, object_name, attribute_name, attribute_type: :text, hint_text: hint_text, label: label, width: width, **args).html
23
25
  end
24
26
 
25
27
  # Generates a input of type +tel+
26
28
  #
27
29
  # @param attribute_name [Symbol] The name of the attribute
28
30
  # @param hint_text [String] The content of the hint. No hint will be injected if left +nil+
31
+ # @param width [Integer,String] sets the width of the input, can be +2+, +3+ +4+, +5+, +10+ or +20+ characters
32
+ # or +one-quarter+, +one-third+, +one-half+, +two-thirds+ or +full+ width of the container
29
33
  # @param [Hash] label configures the associated label
30
34
  # @option label text [String] the label text
31
35
  # @option label size [String] the size of the label font, can be +large+, +medium+, +regular+ or +small+
@@ -41,14 +45,16 @@ module GOVUKDesignSystemFormBuilder
41
45
  # hint_text: 'Include the dialling code',
42
46
  # required: true,
43
47
  # placeholder: '0123 456 789'
44
- def govuk_phone_field(attribute_name, hint_text: nil, label: {}, **args)
45
- Elements::Input.new(self, object_name, attribute_name, attribute_type: :phone, hint_text: hint_text, label: label, **args).html
48
+ def govuk_phone_field(attribute_name, hint_text: nil, label: {}, width: 'full', **args)
49
+ Elements::Input.new(self, object_name, attribute_name, attribute_type: :phone, hint_text: hint_text, label: label, width: width, **args).html
46
50
  end
47
51
 
48
52
  # Generates a input of type +email+
49
53
  #
50
54
  # @param attribute_name [Symbol] The name of the attribute
51
55
  # @param hint_text [String] The content of the hint. No hint will be injected if left +nil+
56
+ # @param width [Integer,String] sets the width of the input, can be +2+, +3+ +4+, +5+, +10+ or +20+ characters
57
+ # or +one-quarter+, +one-third+, +one-half+, +two-thirds+ or +full+ width of the container
52
58
  # @param [Hash] label configures the associated label
53
59
  # @option label text [String] the label text
54
60
  # @option label size [String] the size of the label font, can be +large+, +medium+, +regular+ or +small+
@@ -62,14 +68,16 @@ module GOVUKDesignSystemFormBuilder
62
68
  # = f.govuk_email_field :email_address,
63
69
  # label: { text: 'Enter your email address' },
64
70
  # placeholder: 'ralph.wiggum@springfield.edu'
65
- def govuk_email_field(attribute_name, hint_text: nil, label: {}, **args)
66
- Elements::Input.new(self, object_name, attribute_name, attribute_type: :email, hint_text: hint_text, label: label, **args).html
71
+ def govuk_email_field(attribute_name, hint_text: nil, label: {}, width: 'full', **args)
72
+ Elements::Input.new(self, object_name, attribute_name, attribute_type: :email, hint_text: hint_text, label: label, width: width, **args).html
67
73
  end
68
74
 
69
75
  # Generates a input of type +url+
70
76
  #
71
77
  # @param attribute_name [Symbol] The name of the attribute
72
78
  # @param hint_text [String] The content of the hint. No hint will be injected if left +nil+
79
+ # @param width [Integer,String] sets the width of the input, can be +2+, +3+ +4+, +5+, +10+ or +20+ characters
80
+ # or +one-quarter+, +one-third+, +one-half+, +two-thirds+ or +full+ width of the container
73
81
  # @param [Hash] label configures the associated label
74
82
  # @option label text [String] the label text
75
83
  # @option label size [String] the size of the label font, can be +large+, +medium+, +regular+ or +small+
@@ -83,14 +91,16 @@ module GOVUKDesignSystemFormBuilder
83
91
  # label: { text: 'Enter your favourite website' },
84
92
  # placeholder: 'https://www.gov.uk',
85
93
  # autocomplete: 'url'
86
- def govuk_url_field(attribute_name, hint_text: nil, label: {}, **args)
87
- Elements::Input.new(self, object_name, attribute_name, attribute_type: :url, hint_text: hint_text, label: label, **args).html
94
+ def govuk_url_field(attribute_name, hint_text: nil, label: {}, width: 'full', **args)
95
+ Elements::Input.new(self, object_name, attribute_name, attribute_type: :url, hint_text: hint_text, label: label, width: width, **args).html
88
96
  end
89
97
 
90
98
  # Generates a input of type +number+
91
99
  #
92
100
  # @param attribute_name [Symbol] The name of the attribute
93
101
  # @param hint_text [String] The content of the hint. No hint will be injected if left +nil+
102
+ # @param width [Integer,String] sets the width of the input, can be +2+, +3+ +4+, +5+, +10+ or +20+ characters
103
+ # or +one-quarter+, +one-third+, +one-half+, +two-thirds+ or +full+ width of the container
94
104
  # @param [Hash] label configures the associated label
95
105
  # @option label text [String] the label text
96
106
  # @option label size [String] the size of the label font, can be +large+, +medium+, +regular+ or +small+
@@ -106,11 +116,10 @@ module GOVUKDesignSystemFormBuilder
106
116
  # min: 80,
107
117
  # max: 150,
108
118
  # step: 5
109
- def govuk_number_field(attribute_name, hint_text: nil, label: {}, **args)
110
- Elements::Input.new(self, object_name, attribute_name, attribute_type: :number, hint_text: hint_text, label: label, **args).html
119
+ def govuk_number_field(attribute_name, hint_text: nil, label: {}, width: 'full', **args)
120
+ Elements::Input.new(self, object_name, attribute_name, attribute_type: :number, hint_text: hint_text, label: label, width: width, **args).html
111
121
  end
112
122
 
113
-
114
123
  # Generates a +textarea+ element with a label, optional hint. Also offers
115
124
  # the ability to add the GOV.UK character and word counting components
116
125
  # automatically
@@ -123,6 +132,8 @@ module GOVUKDesignSystemFormBuilder
123
132
  # @option label weight [String] the weight of the label font, can be +bold+ or +regular+
124
133
  # @param max_words [Integer] adds the GOV.UK max word count
125
134
  # @param max_chars [Integer] adds the GOV.UK max characters count
135
+ # @param threshold [Integer] only show the {max_words} and {max_chars} warnings once a threshold (percentage) is reached
136
+ # @param rows [Integer] sets the initial number of rows
126
137
  # @option args [Hash] args additional arguments are applied as attributes to the +textarea+ element
127
138
  # @return [ActiveSupport::SafeBuffer] HTML output
128
139
  # @see https://design-system.service.gov.uk/components/character-count GOV.UK character count component
@@ -134,8 +145,8 @@ module GOVUKDesignSystemFormBuilder
134
145
  # label: { text: 'Tell us about your work history' },
135
146
  # rows: 8,
136
147
  # max_words: 300
137
- def govuk_text_area(attribute_name, hint_text: nil, label: {}, max_words: nil, max_chars: nil, rows: 5, **args)
138
- Elements::TextArea.new(self, object_name, attribute_name, hint_text: hint_text, label: label, max_words: max_words, max_chars: max_chars, rows: rows, **args).html
148
+ def govuk_text_area(attribute_name, hint_text: nil, label: {}, max_words: nil, max_chars: nil, rows: 5, threshold: nil, **args)
149
+ Elements::TextArea.new(self, object_name, attribute_name, hint_text: hint_text, label: label, max_words: max_words, max_chars: max_chars, rows: rows, threshold: threshold, **args).html
139
150
  end
140
151
 
141
152
  # Generates a +select+ element containing +option+ for each member in the provided collection
@@ -411,5 +422,24 @@ module GOVUKDesignSystemFormBuilder
411
422
  def govuk_date_field(attribute_name, hint_text: nil, legend: {}, date_of_birth: false, &block)
412
423
  Elements::Date.new(self, object_name, attribute_name, hint_text: hint_text, legend: legend, date_of_birth: date_of_birth, &block).html
413
424
  end
425
+
426
+ # Generates a summary of errors in the form, each linking to the corresponding
427
+ # part of the form that contains the error
428
+ #
429
+ # @param title [String] the error summary heading
430
+ #
431
+ # @todo Currently the summary anchors link to the inline error messages themselves rather to
432
+ # the accompanying input. More work is required to improve this and it needs to be
433
+ # handled in a less-generic manner. For example, we can't link to a specific radio button
434
+ # if one hasn't been chosen but we should link to a {#govuk_text_field} if one has been left
435
+ # blank
436
+ #
437
+ # @example An error summary with a custom title
438
+ # = f.govuk_error_summary 'Uh-oh, spaghettios'
439
+ #
440
+ # @see https://design-system.service.gov.uk/components/error-summary/ GOV.UK error summary
441
+ def govuk_error_summary(title = 'There is a problem')
442
+ Elements::ErrorSummary.new(self, object_name, title).html
443
+ end
414
444
  end
415
445
  end
@@ -1,11 +1,12 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Containers
3
3
  class CharacterCount < Base
4
- def initialize(builder, max_words:, max_chars:)
4
+ def initialize(builder, max_words:, max_chars:, threshold:)
5
5
  @builder = builder
6
6
  fail ArgumentError, 'limit can be words or chars' if max_words && max_chars
7
7
  @max_words = max_words
8
8
  @max_chars = max_chars
9
+ @threshold = threshold
9
10
  end
10
11
 
11
12
  def html
@@ -14,7 +15,7 @@ module GOVUKDesignSystemFormBuilder
14
15
  @builder.content_tag(
15
16
  'div',
16
17
  class: 'govuk-character-count',
17
- data: { module: 'character-count' }.merge(limit)
18
+ data: { module: 'character-count' }.merge(**limit, **threshold).compact
18
19
  ) do
19
20
  yield
20
21
  end
@@ -30,6 +31,10 @@ module GOVUKDesignSystemFormBuilder
30
31
  end
31
32
  end
32
33
 
34
+ def threshold
35
+ { threshold: @threshold }
36
+ end
37
+
33
38
  def limit?
34
39
  @max_words || @max_chars
35
40
  end
@@ -48,7 +48,7 @@ module GOVUKDesignSystemFormBuilder
48
48
  def descriptors(described_by)
49
49
  return nil unless described_by.present?
50
50
 
51
- Array.wrap(described_by).join(' ')
51
+ Array.wrap(described_by).reject(&:blank?).join(' ')
52
52
  end
53
53
  end
54
54
  end
@@ -13,12 +13,14 @@ module GOVUKDesignSystemFormBuilder
13
13
 
14
14
  def html
15
15
  hint_element = Elements::Hint.new(@builder, @object_name, @attribute_name, @hint_text)
16
+ error_element = Elements::ErrorMessage.new(@builder, @object_name, @attribute_name)
16
17
 
17
18
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
18
- Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, described_by: hint_element.hint_id).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
19
20
  @builder.safe_join(
20
21
  [
21
22
  hint_element.html,
23
+ error_element.html,
22
24
  @block_content,
23
25
  @builder.content_tag('div', class: 'govuk-date-input') do
24
26
  @builder.safe_join(
@@ -69,7 +71,10 @@ module GOVUKDesignSystemFormBuilder
69
71
  end
70
72
 
71
73
  def date_input_classes(width)
72
- %w(govuk-input govuk-date-input__input).push("govuk-input--width-#{width}")
74
+ %w(govuk-input govuk-date-input__input).tap do |classes|
75
+ classes.push("govuk-input--width-#{width}")
76
+ classes.push("govuk-input--error") if has_errors?
77
+ end
73
78
  end
74
79
 
75
80
  def date_input_label_classes
@@ -0,0 +1,68 @@
1
+ module GOVUKDesignSystemFormBuilder
2
+ module Elements
3
+ class ErrorSummary < GOVUKDesignSystemFormBuilder::Base
4
+ def initialize(builder, object_name, title)
5
+ @builder = builder
6
+ @object_name = object_name
7
+ @title = title
8
+ end
9
+
10
+ def html
11
+ return nil unless object_has_errors?
12
+
13
+ @builder.content_tag('div', class: 'govuk-error-summary', **error_summary_attributes) do
14
+ @builder.safe_join(
15
+ [
16
+ @builder.tag.h2(@title, id: error_summary_title_id, class: 'govuk-error-summary__title'),
17
+ @builder.content_tag('div', class: 'govuk-error-summary__body') do
18
+ @builder.content_tag('ul', class: 'govuk-list govuk-error-summary__list') do
19
+ @builder.safe_join(
20
+ @builder.object.errors.messages.map do |attribute, messages|
21
+ error_list_item(attribute, messages)
22
+ end
23
+ )
24
+ end
25
+ end
26
+ ]
27
+ )
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def error_list_item(attribute, messages)
34
+ @builder.content_tag('li') do
35
+ @builder.tag.a(
36
+ messages.join(', '),
37
+ href: ['#', error_id(attribute)].join
38
+ )
39
+ end
40
+ end
41
+
42
+ def error_id(attribute)
43
+ build_id('error', override_attribute_name: attribute)
44
+ end
45
+
46
+ def error_summary_title_id
47
+ 'error-summary-title'
48
+ end
49
+
50
+ def object_has_errors?
51
+ @builder.object.invalid?
52
+ end
53
+
54
+ def error_summary_attributes
55
+ {
56
+ tabindex: -1,
57
+ role: 'alert',
58
+ data: {
59
+ module: 'error-summary'
60
+ },
61
+ aria: {
62
+ labelledby: error_summary_title_id
63
+ }
64
+ }
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,11 +1,11 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  class Input < GOVUKDesignSystemFormBuilder::Base
4
- def initialize(builder, object_name, attribute_name, attribute_type:, hint_text:, label:, **extra_args)
4
+ def initialize(builder, object_name, attribute_name, attribute_type:, hint_text:, label:, width:, **extra_args)
5
5
  super(builder, object_name, attribute_name)
6
6
 
7
- @extra_args = extra_args.dup
8
- @width = @extra_args.delete(:width)
7
+ @width = width
8
+ @extra_args = extra_args
9
9
  @builder_method = [attribute_type, 'field'].join('_')
10
10
  @label = label
11
11
  @hint_text = hint_text
@@ -1,13 +1,14 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
2
  module Elements
3
3
  class TextArea < Base
4
- def initialize(builder, object_name, attribute_name, hint_text:, label:, rows:, max_words:, max_chars:, **extra_args)
4
+ def initialize(builder, object_name, attribute_name, hint_text:, label:, rows:, max_words:, max_chars:, threshold:, **extra_args)
5
5
  super(builder, object_name, attribute_name)
6
6
  @label = label
7
7
  @hint_text = hint_text
8
8
  @extra_args = extra_args
9
9
  @max_words = max_words
10
10
  @max_chars = max_chars
11
+ @threshold = threshold
11
12
  @rows = rows
12
13
  end
13
14
 
@@ -16,7 +17,7 @@ module GOVUKDesignSystemFormBuilder
16
17
  label_element = Elements::Label.new(@builder, @object_name, @attribute_name, @label)
17
18
  error_element = Elements::ErrorMessage.new(@builder, @object_name, @attribute_name)
18
19
 
19
- Containers::CharacterCount.new(@builder, max_words: @max_words, max_chars: @max_chars).html do
20
+ Containers::CharacterCount.new(@builder, max_words: @max_words, max_chars: @max_chars, threshold: @threshold).html do
20
21
  Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do
21
22
  @builder.safe_join(
22
23
  [
@@ -1,3 +1,3 @@
1
1
  module GOVUKDesignSystemFormBuilder
2
- VERSION = '0.7.2'.freeze
2
+ VERSION = '0.7.3'.freeze
3
3
  end
@@ -12,6 +12,7 @@ require 'govuk_design_system_formbuilder/elements/check_boxes/collection_check_b
12
12
  require 'govuk_design_system_formbuilder/elements/check_boxes/label'
13
13
  require 'govuk_design_system_formbuilder/elements/check_boxes/hint'
14
14
  require 'govuk_design_system_formbuilder/elements/error_message'
15
+ require 'govuk_design_system_formbuilder/elements/error_summary'
15
16
  require 'govuk_design_system_formbuilder/elements/submit'
16
17
  require 'govuk_design_system_formbuilder/elements/text_area'
17
18
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_design_system_formbuilder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-29 00:00:00.000000000 Z
11
+ date: 2019-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -143,6 +143,7 @@ files:
143
143
  - lib/govuk_design_system_formbuilder/elements/check_boxes/label.rb
144
144
  - lib/govuk_design_system_formbuilder/elements/date.rb
145
145
  - lib/govuk_design_system_formbuilder/elements/error_message.rb
146
+ - lib/govuk_design_system_formbuilder/elements/error_summary.rb
146
147
  - lib/govuk_design_system_formbuilder/elements/hint.rb
147
148
  - lib/govuk_design_system_formbuilder/elements/input.rb
148
149
  - lib/govuk_design_system_formbuilder/elements/label.rb