simple_form 3.1.0 → 5.0.0

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 (104) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +148 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +278 -68
  5. data/lib/generators/simple_form/install_generator.rb +1 -0
  6. data/lib/generators/simple_form/templates/README +3 -3
  7. data/lib/generators/simple_form/templates/_form.html.erb +2 -0
  8. data/lib/generators/simple_form/templates/_form.html.haml +2 -0
  9. data/lib/generators/simple_form/templates/_form.html.slim +1 -0
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +19 -9
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +367 -63
  12. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +23 -8
  13. data/lib/simple_form/action_view_extensions/builder.rb +1 -0
  14. data/lib/simple_form/action_view_extensions/form_helper.rb +4 -1
  15. data/lib/simple_form/components/errors.rb +15 -2
  16. data/lib/simple_form/components/hints.rb +1 -0
  17. data/lib/simple_form/components/html5.rb +15 -4
  18. data/lib/simple_form/components/label_input.rb +2 -1
  19. data/lib/simple_form/components/labels.rb +12 -5
  20. data/lib/simple_form/components/maxlength.rb +8 -4
  21. data/lib/simple_form/components/min_max.rb +1 -0
  22. data/lib/simple_form/components/minlength.rb +38 -0
  23. data/lib/simple_form/components/pattern.rb +1 -0
  24. data/lib/simple_form/components/placeholders.rb +2 -1
  25. data/lib/simple_form/components/readonly.rb +1 -0
  26. data/lib/simple_form/components.rb +2 -0
  27. data/lib/simple_form/error_notification.rb +1 -0
  28. data/lib/simple_form/form_builder.rb +117 -35
  29. data/lib/simple_form/helpers/autofocus.rb +1 -0
  30. data/lib/simple_form/helpers/disabled.rb +1 -0
  31. data/lib/simple_form/helpers/readonly.rb +1 -0
  32. data/lib/simple_form/helpers/required.rb +1 -0
  33. data/lib/simple_form/helpers/validators.rb +2 -1
  34. data/lib/simple_form/helpers.rb +1 -0
  35. data/lib/simple_form/i18n_cache.rb +1 -0
  36. data/lib/simple_form/inputs/base.rb +36 -12
  37. data/lib/simple_form/inputs/block_input.rb +1 -0
  38. data/lib/simple_form/inputs/boolean_input.rb +14 -3
  39. data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
  40. data/lib/simple_form/inputs/collection_input.rb +7 -5
  41. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +3 -2
  42. data/lib/simple_form/inputs/collection_select_input.rb +1 -0
  43. data/lib/simple_form/inputs/color_input.rb +14 -0
  44. data/lib/simple_form/inputs/date_time_input.rb +13 -8
  45. data/lib/simple_form/inputs/file_input.rb +1 -0
  46. data/lib/simple_form/inputs/grouped_collection_select_input.rb +1 -0
  47. data/lib/simple_form/inputs/hidden_input.rb +1 -0
  48. data/lib/simple_form/inputs/numeric_input.rb +1 -0
  49. data/lib/simple_form/inputs/password_input.rb +2 -1
  50. data/lib/simple_form/inputs/priority_input.rb +1 -4
  51. data/lib/simple_form/inputs/range_input.rb +1 -0
  52. data/lib/simple_form/inputs/string_input.rb +3 -2
  53. data/lib/simple_form/inputs/text_input.rb +2 -1
  54. data/lib/simple_form/inputs.rb +2 -0
  55. data/lib/simple_form/map_type.rb +1 -0
  56. data/lib/simple_form/railtie.rb +1 -0
  57. data/lib/simple_form/tags.rb +7 -2
  58. data/lib/simple_form/version.rb +2 -1
  59. data/lib/simple_form/wrappers/builder.rb +1 -0
  60. data/lib/simple_form/wrappers/leaf.rb +2 -1
  61. data/lib/simple_form/wrappers/many.rb +1 -0
  62. data/lib/simple_form/wrappers/root.rb +2 -0
  63. data/lib/simple_form/wrappers/single.rb +2 -1
  64. data/lib/simple_form/wrappers.rb +1 -0
  65. data/lib/simple_form.rb +79 -14
  66. data/test/action_view_extensions/builder_test.rb +28 -9
  67. data/test/action_view_extensions/form_helper_test.rb +3 -2
  68. data/test/components/custom_components_test.rb +62 -0
  69. data/test/components/label_test.rb +33 -4
  70. data/test/form_builder/association_test.rb +33 -2
  71. data/test/form_builder/button_test.rb +1 -0
  72. data/test/form_builder/error_notification_test.rb +1 -0
  73. data/test/form_builder/error_test.rb +44 -9
  74. data/test/form_builder/general_test.rb +92 -20
  75. data/test/form_builder/hint_test.rb +6 -0
  76. data/test/form_builder/input_field_test.rb +76 -70
  77. data/test/form_builder/label_test.rb +27 -4
  78. data/test/form_builder/wrapper_test.rb +66 -14
  79. data/test/generators/simple_form_generator_test.rb +4 -3
  80. data/test/inputs/boolean_input_test.rb +35 -0
  81. data/test/inputs/collection_check_boxes_input_test.rb +38 -14
  82. data/test/inputs/collection_radio_buttons_input_test.rb +48 -24
  83. data/test/inputs/collection_select_input_test.rb +40 -39
  84. data/test/inputs/color_input_test.rb +10 -0
  85. data/test/inputs/datetime_input_test.rb +12 -8
  86. data/test/inputs/disabled_test.rb +14 -0
  87. data/test/inputs/discovery_test.rb +23 -0
  88. data/test/inputs/file_input_test.rb +1 -0
  89. data/test/inputs/general_test.rb +3 -2
  90. data/test/inputs/grouped_collection_select_input_test.rb +11 -10
  91. data/test/inputs/hidden_input_test.rb +1 -0
  92. data/test/inputs/numeric_input_test.rb +5 -1
  93. data/test/inputs/priority_input_test.rb +7 -6
  94. data/test/inputs/readonly_test.rb +1 -0
  95. data/test/inputs/required_test.rb +45 -0
  96. data/test/inputs/string_input_test.rb +18 -16
  97. data/test/inputs/text_input_test.rb +13 -0
  98. data/test/simple_form_test.rb +1 -0
  99. data/test/support/discovery_inputs.rb +8 -0
  100. data/test/support/misc_helpers.rb +44 -2
  101. data/test/support/mock_controller.rb +7 -1
  102. data/test/support/models.rb +105 -22
  103. data/test/test_helper.rb +14 -3
  104. metadata +42 -36
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'simple_form/i18n_cache'
2
3
  require 'active_support/core_ext/string/output_safety'
3
4
  require 'action_view/helpers'
@@ -21,6 +22,7 @@ module SimpleForm
21
22
  include SimpleForm::Components::HTML5
22
23
  include SimpleForm::Components::LabelInput
23
24
  include SimpleForm::Components::Maxlength
25
+ include SimpleForm::Components::Minlength
24
26
  include SimpleForm::Components::MinMax
25
27
  include SimpleForm::Components::Pattern
26
28
  include SimpleForm::Components::Placeholders
@@ -50,7 +52,7 @@ module SimpleForm
50
52
  enable :hint
51
53
 
52
54
  # Usually disabled, needs to be enabled explicitly passing true as option.
53
- disable :maxlength, :placeholder, :pattern, :min_max
55
+ disable :maxlength, :minlength, :placeholder, :pattern, :min_max
54
56
 
55
57
  def initialize(builder, attribute_name, column, input_type, options = {})
56
58
  super
@@ -70,7 +72,10 @@ module SimpleForm
70
72
  @html_classes = SimpleForm.additional_classes_for(:input) { additional_classes }
71
73
 
72
74
  @input_html_classes = @html_classes.dup
73
- if SimpleForm.input_class && !input_html_classes.empty?
75
+
76
+ input_html_classes = self.input_html_classes
77
+
78
+ if SimpleForm.input_class && input_html_classes.any?
74
79
  input_html_classes << SimpleForm.input_class
75
80
  end
76
81
 
@@ -94,7 +99,7 @@ module SimpleForm
94
99
  end
95
100
 
96
101
  def input_class
97
- "#{lookup_model_names.join("_")}_#{reflection_or_attribute_name}"
102
+ "#{lookup_model_names.join('_')}_#{reflection_or_attribute_name}"
98
103
  end
99
104
 
100
105
  private
@@ -115,7 +120,7 @@ module SimpleForm
115
120
  end
116
121
 
117
122
  def decimal_or_float?
118
- column.number? && column.type != :integer
123
+ column.type == :float || column.type == :decimal
119
124
  end
120
125
 
121
126
  def nested_boolean_style?
@@ -178,24 +183,27 @@ module SimpleForm
178
183
  model_names.shift
179
184
 
180
185
  lookups << :"#{joined_model_names}.#{lookup_action}.#{reflection_or_attribute_name}"
181
- lookups << :"#{joined_model_names}.#{lookup_action}.#{reflection_or_attribute_name}_html"
182
186
  lookups << :"#{joined_model_names}.#{reflection_or_attribute_name}"
183
- lookups << :"#{joined_model_names}.#{reflection_or_attribute_name}_html"
184
187
  end
185
188
  lookups << :"defaults.#{lookup_action}.#{reflection_or_attribute_name}"
186
- lookups << :"defaults.#{lookup_action}.#{reflection_or_attribute_name}_html"
187
189
  lookups << :"defaults.#{reflection_or_attribute_name}"
188
- lookups << :"defaults.#{reflection_or_attribute_name}_html"
189
190
  lookups << default
190
191
 
191
- t(lookups.shift, scope: :"#{i18n_scope}.#{namespace}", default: lookups).presence
192
+ I18n.t(lookups.shift, scope: :"#{i18n_scope}.#{namespace}", default: lookups).presence
192
193
  end
193
194
 
194
195
  def merge_wrapper_options(options, wrapper_options)
195
196
  if wrapper_options
196
- options.merge(wrapper_options) do |_, oldval, newval|
197
- if Array === oldval
198
- oldval + Array(newval)
197
+ wrapper_options = set_input_classes(wrapper_options)
198
+
199
+ wrapper_options.merge(options) do |key, oldval, newval|
200
+ case key.to_s
201
+ when "class"
202
+ Array(oldval) + Array(newval)
203
+ when "data", "aria"
204
+ oldval.merge(newval)
205
+ else
206
+ newval
199
207
  end
200
208
  end
201
209
  else
@@ -203,6 +211,22 @@ module SimpleForm
203
211
  end
204
212
  end
205
213
 
214
+ def set_input_classes(wrapper_options)
215
+ wrapper_options = wrapper_options.dup
216
+ error_class = wrapper_options.delete(:error_class)
217
+ valid_class = wrapper_options.delete(:valid_class)
218
+
219
+ if error_class.present? && has_errors?
220
+ wrapper_options[:class] = "#{wrapper_options[:class]} #{error_class}"
221
+ end
222
+
223
+ if valid_class.present? && valid?
224
+ wrapper_options[:class] = "#{wrapper_options[:class]} #{valid_class}"
225
+ end
226
+
227
+ wrapper_options
228
+ end
229
+
206
230
  def i18n_scope
207
231
  SimpleForm.i18n_scope
208
232
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class BlockInput < Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class BooleanInput < Base
@@ -6,7 +7,7 @@ module SimpleForm
6
7
 
7
8
  if nested_boolean_style?
8
9
  build_hidden_field_for_checkbox +
9
- template.label_tag(nil, class: SimpleForm.boolean_label_class) {
10
+ template.label_tag(nil, class: boolean_label_class) {
10
11
  build_check_box_without_hidden_field(merged_input_options) +
11
12
  inline_label
12
13
  }
@@ -21,7 +22,7 @@ module SimpleForm
21
22
  elsif nested_boolean_style?
22
23
  html_options = label_html_options.dup
23
24
  html_options[:class] ||= []
24
- html_options[:class].push(SimpleForm.boolean_label_class) if SimpleForm.boolean_label_class
25
+ html_options[:class].push(boolean_label_class) if boolean_label_class
25
26
 
26
27
  merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
27
28
 
@@ -36,6 +37,10 @@ module SimpleForm
36
37
 
37
38
  private
38
39
 
40
+ def boolean_label_class
41
+ options[:boolean_label_class] || SimpleForm.boolean_label_class
42
+ end
43
+
39
44
  # Build a checkbox tag using default unchecked value. This allows us to
40
45
  # reuse the method for nested boolean style, but with no unchecked value,
41
46
  # which won't generate the hidden checkbox. This is the default functionality
@@ -55,8 +60,10 @@ module SimpleForm
55
60
  # we need the hidden field to be *outside* the label (otherwise it
56
61
  # generates invalid html - html5 only).
57
62
  def build_hidden_field_for_checkbox
63
+ return "" if !include_hidden? || !unchecked_value
58
64
  options = { value: unchecked_value, id: nil, disabled: input_html_options[:disabled] }
59
- options[:name] = input_html_options[:name] if input_html_options.has_key?(:name)
65
+ options[:name] = input_html_options[:name] if input_html_options.key?(:name)
66
+ options[:form] = input_html_options[:form] if input_html_options.key?(:form)
60
67
 
61
68
  @builder.hidden_field(attribute_name, options)
62
69
  end
@@ -81,6 +88,10 @@ module SimpleForm
81
88
  false
82
89
  end
83
90
 
91
+ def include_hidden?
92
+ options.fetch(:include_hidden, true)
93
+ end
94
+
84
95
  def checked_value
85
96
  options.fetch(:checked_value, '1')
86
97
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class CollectionCheckBoxesInput < CollectionRadioButtonsInput
@@ -10,7 +11,7 @@ module SimpleForm
10
11
  end
11
12
 
12
13
  def build_nested_boolean_style_item_tag(collection_builder)
13
- collection_builder.check_box + collection_builder.text
14
+ collection_builder.check_box + collection_builder.text.to_s
14
15
  end
15
16
 
16
17
  def item_wrapper_class
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class CollectionInput < Base
5
+ BASIC_OBJECT_CLASSES = [String, Integer, Float, NilClass, Symbol, TrueClass, FalseClass]
6
+ BASIC_OBJECT_CLASSES.push(Fixnum, Bignum) unless 1.class == Integer
7
+
4
8
  # Default boolean collection for use with selects/radios when no
5
9
  # collection is given. Always fallback to this boolean collection.
6
10
  # Texts can be translated using i18n in "simple_form.yes" and
@@ -42,7 +46,7 @@ module SimpleForm
42
46
 
43
47
  # Check if :include_blank must be included by default.
44
48
  def skip_include_blank?
45
- (options.keys & [:prompt, :include_blank, :default, :selected]).any? || multiple?
49
+ (options.keys & %i[prompt include_blank default selected]).any? || multiple?
46
50
  end
47
51
 
48
52
  def multiple?
@@ -86,13 +90,11 @@ module SimpleForm
86
90
  end
87
91
 
88
92
  def detect_collection_classes(some_collection = collection)
89
- some_collection.map { |e| e.class }.uniq
93
+ some_collection.map(&:class).uniq
90
94
  end
91
95
 
92
96
  def collection_includes_basic_objects?(collection_classes)
93
- (collection_classes & [
94
- String, Integer, Fixnum, Bignum, Float, NilClass, Symbol, TrueClass, FalseClass
95
- ]).any?
97
+ (collection_classes & BASIC_OBJECT_CLASSES).any?
96
98
  end
97
99
 
98
100
  def translate_collection
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class CollectionRadioButtonsInput < CollectionInput
@@ -6,7 +7,7 @@ module SimpleForm
6
7
 
7
8
  merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
8
9
 
9
- @builder.send("collection_#{input_type}",
10
+ @builder.send(:"collection_#{input_type}",
10
11
  attribute_name, collection, value_method, label_method,
11
12
  input_options, merged_input_options,
12
13
  &collection_block_for_nested_boolean_style
@@ -40,7 +41,7 @@ module SimpleForm
40
41
  end
41
42
 
42
43
  def build_nested_boolean_style_item_tag(collection_builder)
43
- collection_builder.radio_button + collection_builder.text
44
+ collection_builder.radio_button + collection_builder.text.to_s
44
45
  end
45
46
 
46
47
  def item_wrapper_class
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class CollectionSelectInput < CollectionInput
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module SimpleForm
3
+ module Inputs
4
+ class ColorInput < Base
5
+ def input(wrapper_options = nil)
6
+ input_html_options[:type] ||= "color" if html5?
7
+
8
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
9
+
10
+ @builder.text_field(attribute_name, merged_input_options)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class DateTimeInput < Base
@@ -14,16 +15,20 @@ module SimpleForm
14
15
  private
15
16
 
16
17
  def label_target
17
- position = case input_type
18
- when :date, :datetime
19
- date_order = input_options[:order] || I18n.t('date.order')
20
- date_order.first.to_sym
18
+ if use_html5_inputs?
19
+ attribute_name
21
20
  else
22
- :hour
23
- end
21
+ position = case input_type
22
+ when :date, :datetime
23
+ date_order = input_options[:order] || I18n.t('date.order')
24
+ date_order.first.to_sym
25
+ else
26
+ :hour
27
+ end
24
28
 
25
- position = ActionView::Helpers::DateTimeSelector::POSITION[position]
26
- "#{attribute_name}_#{position}i"
29
+ position = ActionView::Helpers::DateTimeSelector::POSITION[position]
30
+ "#{attribute_name}_#{position}i"
31
+ end
27
32
  end
28
33
 
29
34
  def use_html5_inputs?
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class FileInput < Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class GroupedCollectionSelectInput < CollectionInput
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class HiddenInput < Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class NumericInput < Base
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class PasswordInput < Base
4
- enable :placeholder, :maxlength
5
+ enable :placeholder, :maxlength, :minlength
5
6
 
6
7
  def input(wrapper_options = nil)
7
8
  merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class PriorityInput < CollectionSelectInput
@@ -14,10 +15,6 @@ module SimpleForm
14
15
 
15
16
  protected
16
17
 
17
- def has_required?
18
- false
19
- end
20
-
21
18
  def skip_include_blank?
22
19
  super || input_priority.present?
23
20
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class RangeInput < NumericInput
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class StringInput < Base
4
- enable :placeholder, :maxlength, :pattern
5
+ enable :placeholder, :maxlength, :minlength, :pattern
5
6
 
6
7
  def input(wrapper_options = nil)
7
8
  unless string?
@@ -17,7 +18,7 @@ module SimpleForm
17
18
  private
18
19
 
19
20
  def string?
20
- input_type == :string
21
+ input_type == :string || input_type == :citext
21
22
  end
22
23
  end
23
24
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class TextInput < Base
4
- enable :placeholder, :maxlength
5
+ enable :placeholder, :maxlength, :minlength
5
6
 
6
7
  def input(wrapper_options = nil)
7
8
  merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  extend ActiveSupport::Autoload
@@ -9,6 +10,7 @@ module SimpleForm
9
10
  autoload :CollectionInput
10
11
  autoload :CollectionRadioButtonsInput
11
12
  autoload :CollectionSelectInput
13
+ autoload :ColorInput
12
14
  autoload :DateTimeInput
13
15
  autoload :FileInput
14
16
  autoload :GroupedCollectionSelectInput
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_support/core_ext/class/attribute'
2
3
 
3
4
  module SimpleForm
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/railtie'
2
3
 
3
4
  module SimpleForm
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Tags
3
4
  module CollectionExtensions
@@ -47,7 +48,9 @@ module SimpleForm
47
48
  private
48
49
 
49
50
  def render_component(builder)
50
- builder.radio_button + builder.label(class: "collection_radio_buttons")
51
+ label_class = "#{@options[:item_label_class]} collection_radio_buttons".strip
52
+
53
+ builder.radio_button + builder.label(class: label_class)
51
54
  end
52
55
  end
53
56
 
@@ -61,7 +64,9 @@ module SimpleForm
61
64
  private
62
65
 
63
66
  def render_component(builder)
64
- builder.check_box + builder.label(class: "collection_check_boxes")
67
+ label_class = "#{@options[:item_label_class]} collection_check_boxes".strip
68
+
69
+ builder.check_box + builder.label(class: label_class)
65
70
  end
66
71
  end
67
72
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
- VERSION = "3.1.0".freeze
3
+ VERSION = "5.0.0".freeze
3
4
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Wrappers
3
4
  # Provides the builder syntax for components. The builder provides
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Wrappers
3
4
  class Leaf
@@ -11,7 +12,7 @@ module SimpleForm
11
12
  def render(input)
12
13
  method = input.method(@namespace)
13
14
 
14
- if method.arity == 0
15
+ if method.arity.zero?
15
16
  ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })
16
17
 
17
18
  method.call
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Wrappers
3
4
  # A wrapper is an object that holds several components and render them.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Wrappers
3
4
  # `Root` is the root wrapper for all components. It is special cased to
@@ -29,6 +30,7 @@ module SimpleForm
29
30
  end
30
31
  css << (options[:wrapper_error_class] || @defaults[:error_class]) if input.has_errors?
31
32
  css << (options[:wrapper_hint_class] || @defaults[:hint_class]) if input.has_hint?
33
+ css << (options[:wrapper_valid_class] || @defaults[:valid_class]) if input.valid?
32
34
  css.compact
33
35
  end
34
36
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Wrappers
3
4
  # `Single` is an optimization for a wrapper that has only one component.
@@ -19,7 +20,7 @@ module SimpleForm
19
20
  private
20
21
 
21
22
  def html_options(options)
22
- [:label, :input].include?(namespace) ? {} : super
23
+ %i[label input].include?(namespace) ? {} : super
23
24
  end
24
25
  end
25
26
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Wrappers
3
4
  autoload :Builder, 'simple_form/wrappers/builder'