simple_form 3.5.0 → 4.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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/README.md +203 -31
  4. data/lib/generators/simple_form/install_generator.rb +1 -0
  5. data/lib/generators/simple_form/templates/README +3 -3
  6. data/lib/generators/simple_form/templates/_form.html.erb +2 -0
  7. data/lib/generators/simple_form/templates/_form.html.haml +2 -0
  8. data/lib/generators/simple_form/templates/_form.html.slim +1 -0
  9. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +15 -2
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +358 -73
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +18 -6
  12. data/lib/simple_form/action_view_extensions/builder.rb +1 -0
  13. data/lib/simple_form/action_view_extensions/form_helper.rb +1 -0
  14. data/lib/simple_form/components/errors.rb +10 -1
  15. data/lib/simple_form/components/hints.rb +1 -0
  16. data/lib/simple_form/components/html5.rb +1 -0
  17. data/lib/simple_form/components/label_input.rb +2 -1
  18. data/lib/simple_form/components/labels.rb +11 -4
  19. data/lib/simple_form/components/maxlength.rb +4 -13
  20. data/lib/simple_form/components/min_max.rb +1 -0
  21. data/lib/simple_form/components/minlength.rb +5 -14
  22. data/lib/simple_form/components/pattern.rb +1 -0
  23. data/lib/simple_form/components/placeholders.rb +2 -1
  24. data/lib/simple_form/components/readonly.rb +1 -0
  25. data/lib/simple_form/components.rb +1 -0
  26. data/lib/simple_form/error_notification.rb +1 -0
  27. data/lib/simple_form/form_builder.rb +74 -19
  28. data/lib/simple_form/helpers/autofocus.rb +1 -0
  29. data/lib/simple_form/helpers/disabled.rb +1 -0
  30. data/lib/simple_form/helpers/readonly.rb +1 -0
  31. data/lib/simple_form/helpers/required.rb +1 -0
  32. data/lib/simple_form/helpers/validators.rb +2 -1
  33. data/lib/simple_form/helpers.rb +1 -0
  34. data/lib/simple_form/i18n_cache.rb +1 -0
  35. data/lib/simple_form/inputs/base.rb +20 -1
  36. data/lib/simple_form/inputs/block_input.rb +1 -0
  37. data/lib/simple_form/inputs/boolean_input.rb +3 -2
  38. data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
  39. data/lib/simple_form/inputs/collection_input.rb +3 -2
  40. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +2 -1
  41. data/lib/simple_form/inputs/collection_select_input.rb +1 -0
  42. data/lib/simple_form/inputs/date_time_input.rb +1 -0
  43. data/lib/simple_form/inputs/file_input.rb +1 -0
  44. data/lib/simple_form/inputs/grouped_collection_select_input.rb +1 -0
  45. data/lib/simple_form/inputs/hidden_input.rb +1 -0
  46. data/lib/simple_form/inputs/numeric_input.rb +1 -0
  47. data/lib/simple_form/inputs/password_input.rb +1 -0
  48. data/lib/simple_form/inputs/priority_input.rb +1 -0
  49. data/lib/simple_form/inputs/range_input.rb +1 -0
  50. data/lib/simple_form/inputs/string_input.rb +1 -0
  51. data/lib/simple_form/inputs/text_input.rb +1 -0
  52. data/lib/simple_form/inputs.rb +1 -0
  53. data/lib/simple_form/map_type.rb +1 -0
  54. data/lib/simple_form/railtie.rb +1 -0
  55. data/lib/simple_form/tags.rb +1 -0
  56. data/lib/simple_form/version.rb +2 -1
  57. data/lib/simple_form/wrappers/builder.rb +1 -0
  58. data/lib/simple_form/wrappers/leaf.rb +2 -1
  59. data/lib/simple_form/wrappers/many.rb +1 -0
  60. data/lib/simple_form/wrappers/root.rb +2 -0
  61. data/lib/simple_form/wrappers/single.rb +2 -1
  62. data/lib/simple_form/wrappers.rb +1 -0
  63. data/lib/simple_form.rb +58 -7
  64. data/test/action_view_extensions/builder_test.rb +6 -5
  65. data/test/action_view_extensions/form_helper_test.rb +3 -2
  66. data/test/components/custom_components_test.rb +62 -0
  67. data/test/components/label_test.rb +33 -4
  68. data/test/form_builder/association_test.rb +27 -2
  69. data/test/form_builder/button_test.rb +1 -0
  70. data/test/form_builder/error_notification_test.rb +1 -0
  71. data/test/form_builder/error_test.rb +6 -0
  72. data/test/form_builder/general_test.rb +44 -3
  73. data/test/form_builder/hint_test.rb +6 -0
  74. data/test/form_builder/input_field_test.rb +27 -1
  75. data/test/form_builder/label_test.rb +9 -3
  76. data/test/form_builder/wrapper_test.rb +24 -4
  77. data/test/generators/simple_form_generator_test.rb +4 -3
  78. data/test/inputs/boolean_input_test.rb +9 -0
  79. data/test/inputs/collection_check_boxes_input_test.rb +30 -14
  80. data/test/inputs/collection_radio_buttons_input_test.rb +40 -24
  81. data/test/inputs/collection_select_input_test.rb +40 -39
  82. data/test/inputs/datetime_input_test.rb +5 -4
  83. data/test/inputs/disabled_test.rb +1 -0
  84. data/test/inputs/discovery_test.rb +1 -0
  85. data/test/inputs/file_input_test.rb +1 -0
  86. data/test/inputs/general_test.rb +3 -2
  87. data/test/inputs/grouped_collection_select_input_test.rb +11 -10
  88. data/test/inputs/hidden_input_test.rb +1 -0
  89. data/test/inputs/numeric_input_test.rb +2 -1
  90. data/test/inputs/priority_input_test.rb +1 -0
  91. data/test/inputs/readonly_test.rb +1 -0
  92. data/test/inputs/required_test.rb +1 -0
  93. data/test/inputs/string_input_test.rb +2 -1
  94. data/test/inputs/text_input_test.rb +1 -0
  95. data/test/simple_form_test.rb +1 -0
  96. data/test/support/discovery_inputs.rb +1 -0
  97. data/test/support/misc_helpers.rb +16 -1
  98. data/test/support/mock_controller.rb +4 -0
  99. data/test/support/models.rb +44 -14
  100. data/test/test_helper.rb +2 -0
  101. metadata +5 -15
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Components
3
4
  module Labels
@@ -6,18 +7,24 @@ module SimpleForm
6
7
  module ClassMethods #:nodoc:
7
8
  def translate_required_html
8
9
  i18n_cache :translate_required_html do
9
- I18n.t(:"simple_form.required.html", default:
10
- %[<abbr title="#{translate_required_text}">#{translate_required_mark}</abbr>]
10
+ I18n.t(:"required.html", scope: i18n_scope, default:
11
+ %(<abbr title="#{translate_required_text}">#{translate_required_mark}</abbr>)
11
12
  )
12
13
  end
13
14
  end
14
15
 
15
16
  def translate_required_text
16
- I18n.t(:"simple_form.required.text", default: 'required')
17
+ I18n.t(:"required.text", scope: i18n_scope, default: 'required')
17
18
  end
18
19
 
19
20
  def translate_required_mark
20
- I18n.t(:"simple_form.required.mark", default: '*')
21
+ I18n.t(:"required.mark", scope: i18n_scope, default: '*')
22
+ end
23
+
24
+ private
25
+
26
+ def i18n_scope
27
+ SimpleForm.i18n_scope
21
28
  end
22
29
  end
23
30
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Components
3
4
  # Needs to be enabled in order to do automatic lookups.
@@ -27,19 +28,9 @@ module SimpleForm
27
28
  length_validator.options[:tokenizer]
28
29
  end
29
30
 
30
- # Use validation with tokenizer if version of Rails is less than 5,
31
- # if not validate without the tokenizer, if version is greater than Rails 4.
32
- if ActionPack::VERSION::STRING < '5'
33
- def maximum_length_value_from(length_validator)
34
- if length_validator && !has_tokenizer?(length_validator)
35
- length_validator.options[:is] || length_validator.options[:maximum]
36
- end
37
- end
38
- elsif ActionPack::VERSION::STRING >= '5'
39
- def maximum_length_value_from(length_validator)
40
- if length_validator
41
- length_validator.options[:is] || length_validator.options[:maximum]
42
- end
31
+ def maximum_length_value_from(length_validator)
32
+ if length_validator
33
+ length_validator.options[:is] || length_validator.options[:maximum]
43
34
  end
44
35
  end
45
36
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Components
3
4
  module MinMax
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Components
3
4
  # Needs to be enabled in order to do automatic lookups.
4
5
  module Minlength
5
6
  def minlength(wrapper_options = nil)
6
- input_html_options[:minlength] ||= minimum_length_from_validation || limit
7
+ input_html_options[:minlength] ||= minimum_length_from_validation
7
8
  nil
8
9
  end
9
10
 
@@ -27,19 +28,9 @@ module SimpleForm
27
28
  length_validator.options[:tokenizer]
28
29
  end
29
30
 
30
- # Use validation with tokenizer if version of Rails is less than 5,
31
- # if not validate without the tokenizer, if version is greater than Rails 4.
32
- if ActionPack::VERSION::STRING < '5'
33
- def minimum_length_value_from(length_validator)
34
- if length_validator && !has_tokenizer?(length_validator)
35
- length_validator.options[:is] || length_validator.options[:minimum]
36
- end
37
- end
38
- elsif ActionPack::VERSION::STRING >= '5'
39
- def minimum_length_value_from(length_validator)
40
- if length_validator
41
- length_validator.options[:is] || length_validator.options[:minimum]
42
- end
31
+ def minimum_length_value_from(length_validator)
32
+ if length_validator
33
+ length_validator.options[:is] || length_validator.options[:minimum]
43
34
  end
44
35
  end
45
36
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Components
3
4
  # Needs to be enabled in order to do automatic lookups.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Components
3
4
  # Needs to be enabled in order to do automatic lookups.
@@ -7,7 +8,7 @@ module SimpleForm
7
8
  nil
8
9
  end
9
10
 
10
- def placeholder_text
11
+ def placeholder_text(wrapper_options = nil)
11
12
  placeholder = options[:placeholder]
12
13
  placeholder.is_a?(String) ? placeholder : translate_from_namespace(:placeholders)
13
14
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Components
3
4
  # Needs to be enabled in order to do automatic lookups.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  # Components are a special type of helpers that can work on their own.
3
4
  # For example, by using a component, it will automatically change the
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  class ErrorNotification
3
4
  delegate :object, :object_name, :template, to: :@builder
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_support/core_ext/object/deep_dup'
2
3
  require 'simple_form/map_type'
3
4
  require 'simple_form/tags'
@@ -12,25 +13,25 @@ module SimpleForm
12
13
  'update' => 'edit'
13
14
  }
14
15
 
15
- ATTRIBUTE_COMPONENTS = [:html5, :min_max, :maxlength, :minlength, :placeholder, :pattern, :readonly]
16
+ ATTRIBUTE_COMPONENTS = %i[html5 min_max maxlength minlength placeholder pattern readonly]
16
17
 
17
18
  extend MapType
18
19
  include SimpleForm::Inputs
19
20
 
20
- map_type :text, to: SimpleForm::Inputs::TextInput
21
- map_type :file, to: SimpleForm::Inputs::FileInput
22
- map_type :string, :email, :search, :tel, :url, :uuid, to: SimpleForm::Inputs::StringInput
23
- map_type :password, to: SimpleForm::Inputs::PasswordInput
24
- map_type :integer, :decimal, :float, to: SimpleForm::Inputs::NumericInput
25
- map_type :range, to: SimpleForm::Inputs::RangeInput
26
- map_type :check_boxes, to: SimpleForm::Inputs::CollectionCheckBoxesInput
27
- map_type :radio_buttons, to: SimpleForm::Inputs::CollectionRadioButtonsInput
28
- map_type :select, to: SimpleForm::Inputs::CollectionSelectInput
29
- map_type :grouped_select, to: SimpleForm::Inputs::GroupedCollectionSelectInput
30
- map_type :date, :time, :datetime, to: SimpleForm::Inputs::DateTimeInput
31
- map_type :country, :time_zone, to: SimpleForm::Inputs::PriorityInput
32
- map_type :boolean, to: SimpleForm::Inputs::BooleanInput
33
- map_type :hidden, to: SimpleForm::Inputs::HiddenInput
21
+ map_type :text, :hstore, :json, :jsonb, to: SimpleForm::Inputs::TextInput
22
+ map_type :file, to: SimpleForm::Inputs::FileInput
23
+ map_type :string, :email, :search, :tel, :url, :uuid, :citext, to: SimpleForm::Inputs::StringInput
24
+ map_type :password, to: SimpleForm::Inputs::PasswordInput
25
+ map_type :integer, :decimal, :float, to: SimpleForm::Inputs::NumericInput
26
+ map_type :range, to: SimpleForm::Inputs::RangeInput
27
+ map_type :check_boxes, to: SimpleForm::Inputs::CollectionCheckBoxesInput
28
+ map_type :radio_buttons, to: SimpleForm::Inputs::CollectionRadioButtonsInput
29
+ map_type :select, to: SimpleForm::Inputs::CollectionSelectInput
30
+ map_type :grouped_select, to: SimpleForm::Inputs::GroupedCollectionSelectInput
31
+ map_type :date, :time, :datetime, to: SimpleForm::Inputs::DateTimeInput
32
+ map_type :country, :time_zone, to: SimpleForm::Inputs::PriorityInput
33
+ map_type :boolean, to: SimpleForm::Inputs::BooleanInput
34
+ map_type :hidden, to: SimpleForm::Inputs::HiddenInput
34
35
 
35
36
  def self.discovery_cache
36
37
  @discovery_cache ||= {}
@@ -38,6 +39,7 @@ module SimpleForm
38
39
 
39
40
  def initialize(*) #:nodoc:
40
41
  super
42
+ @object = convert_to_model(@object)
41
43
  @defaults = options[:defaults]
42
44
  @wrapper = SimpleForm.wrapper(options[:wrapper] || SimpleForm.default_wrapper)
43
45
  end
@@ -136,6 +138,29 @@ module SimpleForm
136
138
  # <input class="string required" id="user_name" maxlength="100"
137
139
  # name="user[name]" type="text" value="Carlos" />
138
140
  #
141
+ # It also support validation classes once it is configured.
142
+ #
143
+ # # config/initializers/simple_form.rb
144
+ # SimpleForm.setup do |config|
145
+ # config.input_field_valid_class = 'is-valid'
146
+ # config.input_field_error_class = 'is-invalid'
147
+ # end
148
+ #
149
+ # simple_form_for @user do |f|
150
+ # f.input_field :name
151
+ # end
152
+ #
153
+ # When the validation happens, the input will be rendered with
154
+ # the class configured according to the validation:
155
+ #
156
+ # - when the input is valid:
157
+ #
158
+ # <input class="is-valid string required" id="user_name" value="Carlos" />
159
+ #
160
+ # - when the input is invalid:
161
+ #
162
+ # <input class="is-invalid string required" id="user_name" value="" />
163
+ #
139
164
  def input_field(attribute_name, options = {})
140
165
  components = (wrapper.components.map(&:namespace) & ATTRIBUTE_COMPONENTS)
141
166
 
@@ -145,7 +170,7 @@ module SimpleForm
145
170
 
146
171
  input = find_input(attribute_name, options)
147
172
  wrapper = find_wrapper(input.input_type, options)
148
- components = components.concat([:input]).map { |component| SimpleForm::Wrappers::Leaf.new(component) }
173
+ components = build_input_field_components(components.push(:input))
149
174
 
150
175
  SimpleForm::Wrappers::Root.new(components, wrapper.options.merge(wrapper: false)).render input
151
176
  end
@@ -461,13 +486,17 @@ module SimpleForm
461
486
  relation = reflection.klass.all
462
487
 
463
488
  if reflection.respond_to?(:scope) && reflection.scope
464
- relation = reflection.klass.instance_exec(&reflection.scope)
489
+ if reflection.scope.parameters.any?
490
+ relation = reflection.klass.instance_exec(object, &reflection.scope)
491
+ else
492
+ relation = reflection.klass.instance_exec(&reflection.scope)
493
+ end
465
494
  else
466
495
  order = reflection.options[:order]
467
496
  conditions = reflection.options[:conditions]
468
497
  conditions = object.instance_exec(&conditions) if conditions.respond_to?(:call)
469
498
 
470
- relation = relation.where(conditions)
499
+ relation = relation.where(conditions) if relation.respond_to?(:where)
471
500
  relation = relation.order(order) if relation.respond_to?(:order)
472
501
  end
473
502
 
@@ -521,7 +550,7 @@ module SimpleForm
521
550
  case input_type
522
551
  when :timestamp
523
552
  :datetime
524
- when :string, nil
553
+ when :string, :citext, nil
525
554
  case attribute_name.to_s
526
555
  when /password/ then :password
527
556
  when /time_zone/ then :time_zone
@@ -640,5 +669,31 @@ module SimpleForm
640
669
 
641
670
  nil
642
671
  end
672
+
673
+ def build_input_field_components(components)
674
+ components.map do |component|
675
+ if component == :input
676
+ SimpleForm::Wrappers::Leaf.new(component, build_input_field_options)
677
+ else
678
+ SimpleForm::Wrappers::Leaf.new(component)
679
+ end
680
+ end
681
+ end
682
+
683
+ def build_input_field_options
684
+ input_field_options = {}
685
+ valid_class = SimpleForm.input_field_valid_class
686
+ error_class = SimpleForm.input_field_error_class
687
+
688
+ if error_class.present?
689
+ input_field_options[:error_class] = error_class
690
+ end
691
+
692
+ if valid_class.present?
693
+ input_field_options[:valid_class] = valid_class
694
+ end
695
+
696
+ input_field_options
697
+ end
643
698
  end
644
699
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Helpers
3
4
  module Autofocus
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Helpers
3
4
  module Disabled
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Helpers
3
4
  module Readonly
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Helpers
3
4
  module Required
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Helpers
3
4
  module Validators
@@ -24,7 +25,7 @@ module SimpleForm
24
25
  end
25
26
 
26
27
  def action_validator_match?(validator)
27
- return true if !validator.options.include?(:on)
28
+ return true unless validator.options.include?(:on)
28
29
 
29
30
  case validator.options[:on]
30
31
  when :save
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  # Helpers are made of several helpers that cannot be turned on automatically.
3
4
  # For instance, disabled cannot be turned on automatically, it requires the
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  # A lot of configuration values are retrived from I18n,
3
4
  # like boolean collection, required string. This module provides
@@ -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'
@@ -95,7 +96,7 @@ module SimpleForm
95
96
  end
96
97
 
97
98
  def input_class
98
- "#{lookup_model_names.join("_")}_#{reflection_or_attribute_name}"
99
+ "#{lookup_model_names.join('_')}_#{reflection_or_attribute_name}"
99
100
  end
100
101
 
101
102
  private
@@ -190,6 +191,8 @@ module SimpleForm
190
191
 
191
192
  def merge_wrapper_options(options, wrapper_options)
192
193
  if wrapper_options
194
+ wrapper_options = set_input_classes(wrapper_options)
195
+
193
196
  wrapper_options.merge(options) do |key, oldval, newval|
194
197
  case key.to_s
195
198
  when "class"
@@ -205,6 +208,22 @@ module SimpleForm
205
208
  end
206
209
  end
207
210
 
211
+ def set_input_classes(wrapper_options)
212
+ wrapper_options = wrapper_options.dup
213
+ error_class = wrapper_options.delete(:error_class)
214
+ valid_class = wrapper_options.delete(:valid_class)
215
+
216
+ if error_class.present? && has_errors?
217
+ wrapper_options[:class] = "#{wrapper_options[:class]} #{error_class}"
218
+ end
219
+
220
+ if valid_class.present? && valid?
221
+ wrapper_options[:class] = "#{wrapper_options[:class]} #{valid_class}"
222
+ end
223
+
224
+ wrapper_options
225
+ end
226
+
208
227
  def i18n_scope
209
228
  SimpleForm.i18n_scope
210
229
  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
@@ -59,9 +60,9 @@ module SimpleForm
59
60
  # we need the hidden field to be *outside* the label (otherwise it
60
61
  # generates invalid html - html5 only).
61
62
  def build_hidden_field_for_checkbox
62
- return "" unless include_hidden?
63
+ return "" if !include_hidden? || !unchecked_value
63
64
  options = { value: unchecked_value, id: nil, disabled: input_html_options[:disabled] }
64
- 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)
65
66
 
66
67
  @builder.hidden_field(attribute_name, options)
67
68
  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,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class CollectionInput < Base
@@ -45,7 +46,7 @@ module SimpleForm
45
46
 
46
47
  # Check if :include_blank must be included by default.
47
48
  def skip_include_blank?
48
- (options.keys & [:prompt, :include_blank, :default, :selected]).any? || multiple?
49
+ (options.keys & %i[prompt include_blank default selected]).any? || multiple?
49
50
  end
50
51
 
51
52
  def multiple?
@@ -89,7 +90,7 @@ module SimpleForm
89
90
  end
90
91
 
91
92
  def detect_collection_classes(some_collection = collection)
92
- some_collection.map { |e| e.class }.uniq
93
+ some_collection.map(&:class).uniq
93
94
  end
94
95
 
95
96
  def collection_includes_basic_objects?(collection_classes)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class CollectionRadioButtonsInput < CollectionInput
@@ -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
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class DateTimeInput < Base
@@ -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,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class PasswordInput < Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class PriorityInput < CollectionSelectInput
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class RangeInput < NumericInput
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class StringInput < Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  class TextInput < Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
3
  module Inputs
3
4
  extend ActiveSupport::Autoload
@@ -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
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SimpleForm
2
- VERSION = "3.5.0".freeze
3
+ VERSION = "4.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'