diff --git a/Gemfile.lock b/Gemfile.lock
index 1eb2bf2..0508822 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -83,6 +83,7 @@ GEM
crass (1.0.6)
date (3.3.3)
diff-lcs (1.5.0)
+ docile (1.4.0)
erubi (1.12.0)
execjs (2.8.1)
ffi (1.15.5)
@@ -176,6 +177,12 @@ GEM
sprockets (> 3.0)
sprockets-rails
tilt
+ simplecov (0.22.0)
+ docile (~> 1.1)
+ simplecov-html (~> 0.11)
+ simplecov_json_formatter (~> 0.1)
+ simplecov-html (0.12.3)
+ simplecov_json_formatter (0.1.4)
sprockets (4.2.0)
concurrent-ruby (~> 1.0)
rack (>= 2.2.4, < 4)
@@ -207,6 +214,7 @@ DEPENDENCIES
rake (~> 13.0)
rspec-rails
sassc-rails
+ simplecov
sprockets-rails
sqlite3 (~> 1.4)
diff --git a/demo/app/views/users/_vertical_form.html.erb b/demo/app/views/users/_vertical_form.html.erb
index aa51aae..f060233 100644
--- a/demo/app/views/users/_vertical_form.html.erb
+++ b/demo/app/views/users/_vertical_form.html.erb
@@ -4,7 +4,7 @@
<%= bootstrap_form_for @user, bootstrap_form: {} do |form| %>
- <%= form.text_field :name, autocomplete: "new-name", bootstrap_form: {} %>
+ <%= form.text_field :name, autocomplete: "new-name", class: "dsds", bootstrap_form: {} %>
<%= form.text_field :email, autocomplete: "new-email", bootstrap_form: {} %>
<%= form.text_field :password, autocomplete: "new-password" %>
<%= form.phone_field :mobile_number %>
diff --git a/gemfiles/common.gemfile b/gemfiles/common.gemfile
index e083c0b..e390100 100644
--- a/gemfiles/common.gemfile
+++ b/gemfiles/common.gemfile
@@ -18,6 +18,9 @@ gem "bootstrap", "~> 5.3.0.alpha3"
# Use sqlite3 as the database for Active Record
gem "sqlite3", "~> 1.4"
+# Library to show coverage of the code.
+gem "simplecov"
+
group :development do
gem "puma"
end
diff --git a/lib/rails_bootstrap_form/bootstrap_form_options.rb b/lib/rails_bootstrap_form/bootstrap_form_options.rb
index e857c6a..aa2236f 100644
--- a/lib/rails_bootstrap_form/bootstrap_form_options.rb
+++ b/lib/rails_bootstrap_form/bootstrap_form_options.rb
@@ -90,6 +90,14 @@ class BootstrapFormOptions
# Default is `false`.
attr_accessor :switch
+ # Controls the HTML attributes and options that will be added to the field wrapper.
+ # Default is `{}`.
+ attr_accessor :wrapper_options
+
+ # Option to specify the size of input groups and fields.
+ # The valid values are `sm` and `lg`. The default value is `nil`.
+ attr_accessor :size
+
def initialize(options = {})
set_defaults
set_bootstrap_form_options(options)
@@ -107,10 +115,6 @@ def vertical?
@layout.to_s == "vertical"
end
- def floating?
- @layout.to_s == "floating"
- end
-
# This will return a copy of `BootstrapFormOptions` object with new options set
# that don't affect original object. This way we can have options specific
# to a given form field. For example, we can change grid just for one field:
@@ -152,6 +156,10 @@ def set_defaults
@static_field_class = "form-control-plaintext"
@switch = false
+
+ @wrapper_options = {}
+
+ @size = nil
end
private :set_defaults
diff --git a/lib/rails_bootstrap_form/components/check_box.rb b/lib/rails_bootstrap_form/components/check_box.rb
index 27b8675..bf4d2b5 100644
--- a/lib/rails_bootstrap_form/components/check_box.rb
+++ b/lib/rails_bootstrap_form/components/check_box.rb
@@ -27,6 +27,12 @@ def check_box_label(attribute, checked_value, options, bootstrap_options, &block
end
end
+ def check_box_wrapper_options(bootstrap_options)
+ {}.tap do |option|
+ option[:class] = check_box_wrapper_class(bootstrap_options)
+ end.merge(bootstrap_options.wrapper_options)
+ end
+
def check_box_label_text(attribute, options, bootstrap_options, &block)
block ? capture(&block) : label_text(attribute, bootstrap_options)
end
@@ -55,7 +61,7 @@ def check_box_label_class(attribute, bootstrap_options, options)
def check_box_wrapper_class(bootstrap_options)
classes = Array("form-check")
classes << "form-switch" if bootstrap_options.switch
- classes << "form-check-inline" if bootstrap_options.inline?
+ classes << (bootstrap_options.inline? ? "form-check-inline" : "mb-3")
classes.flatten.compact
end
diff --git a/lib/rails_bootstrap_form/components/labels.rb b/lib/rails_bootstrap_form/components/labels.rb
index 5a6bfa5..e031fac 100644
--- a/lib/rails_bootstrap_form/components/labels.rb
+++ b/lib/rails_bootstrap_form/components/labels.rb
@@ -8,12 +8,15 @@ module Labels
extend ActiveSupport::Concern
def self.included(base_class)
- def draw_label(attribute, bootstrap_options)
+ def draw_label(attribute, options, bootstrap_options)
unless bootstrap_options.skip_label
- label_class = label_classes(attribute, bootstrap_options)
+ label_options = {
+ class: label_classes(attribute, bootstrap_options)
+ }
+ label_options[:for] = options[:id] if options[:id].present?
label_text = label_text(attribute, bootstrap_options)
- label(attribute, label_text, class: label_class)
+ label(attribute, label_text, label_options)
end
end
diff --git a/lib/rails_bootstrap_form/components/radio_button.rb b/lib/rails_bootstrap_form/components/radio_button.rb
index 6882b03..43e77a0 100644
--- a/lib/rails_bootstrap_form/components/radio_button.rb
+++ b/lib/rails_bootstrap_form/components/radio_button.rb
@@ -28,6 +28,12 @@ def radio_button_label(attribute, value, options, bootstrap_options)
end
end
+ def radio_button_wrapper_options(bootstrap_options)
+ {}.tap do |option|
+ option[:class] = radio_button_wrapper_class(bootstrap_options)
+ end.merge(bootstrap_options.wrapper_options)
+ end
+
def radio_button_value(attribute, value)
# label's `for` attribute needs to match checkbox tag's id,
# IE sanitized value, IE
@@ -51,7 +57,7 @@ def radio_button_label_class(attribute, bootstrap_options, options)
def radio_button_wrapper_class(bootstrap_options)
classes = Array("form-check")
- classes << "form-check-inline" if bootstrap_options.inline?
+ classes << (bootstrap_options.inline? ? "form-check-inline" : "mb-3")
classes.flatten.compact
end
diff --git a/lib/rails_bootstrap_form/field_wrapper_builder.rb b/lib/rails_bootstrap_form/field_wrapper_builder.rb
index 795e290..ab9b37f 100644
--- a/lib/rails_bootstrap_form/field_wrapper_builder.rb
+++ b/lib/rails_bootstrap_form/field_wrapper_builder.rb
@@ -13,11 +13,11 @@ def field_wrapper_builder(attribute, options, html_options = nil, &block)
end
def field_wrapper(attribute, bootstrap_options, options, &block)
- label = draw_label(attribute, bootstrap_options)
+ label = draw_label(attribute, options, bootstrap_options)
help_text = help_text(attribute, bootstrap_options)
if bootstrap_options.floating
- tag.div(class: field_wrapper_classes) do
+ tag.div(**field_wrapper_options(bootstrap_options)) do
concat(input_group_wrapper(attribute, bootstrap_options) do
tag.div(class: floating_label_classes(attribute)) do
concat(capture(&block))
@@ -27,7 +27,7 @@ def field_wrapper(attribute, bootstrap_options, options, &block)
concat(help_text)
end
else
- tag.div(class: field_wrapper_classes) do
+ tag.div(**field_wrapper_options(bootstrap_options)) do
concat(label)
concat(input_group_wrapper(attribute, bootstrap_options) do
capture(&block)
@@ -37,14 +37,17 @@ def field_wrapper(attribute, bootstrap_options, options, &block)
end
end
+ def field_wrapper_options(bootstrap_options)
+ {}.tap do |option|
+ option[:class] = field_wrapper_classes
+ end.merge(bootstrap_options.wrapper_options)
+ end
+
def field_wrapper_classes
classes = [form_wrapper_default_class]
classes.flatten.compact
end
- def field_wrapper_options
- end
-
def form_wrapper_default_class
"mb-3"
end
@@ -52,14 +55,17 @@ def form_wrapper_default_class
def field_css_options(attribute, bootstrap_options, options, html_options)
css_options = (html_options || options)
- field_classes = [
+ field_classes = Array(options[:class])
+ field_classes << [
bootstrap_options.field_class,
bootstrap_options.additional_field_class
]
field_classes << "is-invalid" if is_invalid?(attribute)
+ if is_size_valid?(bootstrap_options)
+ field_classes << "#{bootstrap_options.field_class}-#{bootstrap_options.size}"
+ end
css_options[:class] = field_classes.flatten.compact
-
css_options.merge!(required_field_options(attribute, options))
if bootstrap_options.floating
diff --git a/lib/rails_bootstrap_form/input_group_builder.rb b/lib/rails_bootstrap_form/input_group_builder.rb
index b9be842..2289f61 100644
--- a/lib/rails_bootstrap_form/input_group_builder.rb
+++ b/lib/rails_bootstrap_form/input_group_builder.rb
@@ -26,7 +26,10 @@ def input_group_wrapper(attribute, bootstrap_options, &block)
end
def input_group_classes(attribute, bootstrap_options)
- classes = ["input-group", bootstrap_options.additional_input_group_class]
+ classes = Array("input-group") << bootstrap_options.additional_input_group_class
+ if is_size_valid?(bootstrap_options)
+ classes << "input-group-#{bootstrap_options.size}"
+ end
# Require `has-validation` class if field has errors.
classes << "has-validation" if is_invalid?(attribute)
classes.flatten.compact
diff --git a/lib/rails_bootstrap_form/inputs.rb b/lib/rails_bootstrap_form/inputs.rb
index 931e636..a030a94 100644
--- a/lib/rails_bootstrap_form/inputs.rb
+++ b/lib/rails_bootstrap_form/inputs.rb
@@ -45,7 +45,7 @@ module Inputs
end
DATE_SELECT_HELPERS.each do |field_tag_name|
- define_method(field_tag_name) do |attribute, options = {}, html_options = {}, &block|
+ define_method(field_tag_name) do |attribute, options = {}, html_options = {}|
options = {bootstrap_form: {field_class: "form-select"}}.deep_merge!(options)
field_wrapper_builder(attribute, options, html_options) do
@@ -137,7 +137,7 @@ def check_box(attribute, options = {}, checked_value = "1", unchecked_value = "0
check_box_label = check_box_label(attribute, checked_value, options, bootstrap_options, &block)
- check_box_html = tag.div(class: check_box_wrapper_class(bootstrap_options)) do
+ check_box_html = tag.div(**check_box_wrapper_options(bootstrap_options)) do
concat(check_box_field)
concat(check_box_label)
concat(check_box_help_text) unless bootstrap_options.inline?
@@ -157,7 +157,7 @@ def radio_button(attribute, value, options = {})
radio_button_label = radio_button_label(attribute, value, options, bootstrap_options)
- radio_button_html = tag.div(class: radio_button_wrapper_class(bootstrap_options)) do
+ radio_button_html = tag.div(**radio_button_wrapper_options(bootstrap_options)) do
concat(radio_button_field)
concat(radio_button_label)
concat(radio_button_help_text) unless bootstrap_options.inline?
diff --git a/lib/rails_bootstrap_form/inputs/base.rb b/lib/rails_bootstrap_form/inputs/base.rb
index 5bb314e..4b27014 100644
--- a/lib/rails_bootstrap_form/inputs/base.rb
+++ b/lib/rails_bootstrap_form/inputs/base.rb
@@ -17,7 +17,11 @@ def control_specific_class(field_tag_name)
"rails-bootstrap-forms-#{field_tag_name.to_s.tr("_", "-")}"
end
- private :collection_input_checked?, :control_specific_class
+ def is_size_valid?(bootstrap_options)
+ bootstrap_options.size && %i(sm lg).include?(bootstrap_options.size)
+ end
+
+ private :collection_input_checked?, :control_specific_class, :is_size_valid?
end
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 618fbcc..9522ded 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -5,6 +5,7 @@
ENV["RAILS_ENV"] ||= "test"
require_relative "../demo/config/environment"
+require "simplecov"
def spec_root
Pathname.new(File.expand_path(__dir__))
@@ -14,6 +15,13 @@ def test_directory_path
spec_root / "test"
end
+SimpleCov.start "rails" do
+ add_filter "spec/"
+ add_filter ".github/"
+ add_filter "lib/generators/templates/"
+ add_filter "lib/rails_bootstrap_form/version"
+end
+
RSpec.configure do |config|
config.color = true
config.formatter = :documentation