simple_form 3.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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'