Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Builder using modules #134

Merged
merged 10 commits into from
Feb 4, 2023
Prev Previous commit
Next Next commit
Extract ViewComponent::Form::Helpers::RailsBackports
  • Loading branch information
Spone committed Feb 2, 2023
commit a054f1be4dcaff41711fa23fc008c73628074b7d
20 changes: 1 addition & 19 deletions lib/view_component/form/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def initialize(*)
end

include ViewComponent::Form::Helpers::Rails
include ViewComponent::Form::Helpers::RailsBackports

def error_message(method, options = {})
render_component(:error_message, @object_name, method, objectify_options(options))
Expand All @@ -47,25 +48,6 @@ def hint(method, text = nil, options = {}, &block)
render_component(:hint, @object_name, method, text, objectify_options(options), &block)
end

# Backport field_id from Rails 7.0
if Rails::VERSION::MAJOR < 7
def field_id(method_name, *suffixes, namespace: @options[:namespace], index: @index)
object_name = object_name.model_name.singular if object_name.respond_to?(:model_name)

sanitized_object_name = object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").delete_suffix("_")

sanitized_method_name = method_name.to_s.delete_suffix("?")

[
namespace,
sanitized_object_name.presence,
(index unless sanitized_object_name.empty?),
sanitized_method_name,
*suffixes
].tap(&:compact!).join("_")
end
end

private

def render_component(component_name, *args, &block)
Expand Down
232 changes: 114 additions & 118 deletions lib/view_component/form/helpers/rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ module Form
module Helpers
# rubocop:disable Metrics/ModuleLength
module Rails
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def self.included(base)
# rubocop:disable Metrics/BlockLength
base.class_eval do
(field_helpers - %i[
check_box
Expand All @@ -34,141 +32,139 @@ def #{selector}(method, options = {}) # def text_field(method, options = {})
RUBY_EVAL
end
alias_method :phone_field, :telephone_field
end
end
# rubocop:enable Metrics/MethodLength

# See: https://github.com/rails/rails/blob/33d60cb02dcac26d037332410eabaeeb0bdc384c/actionview/lib/action_view/helpers/form_helper.rb#L2280
def label(method, text = nil, options = {}, &block)
render_component(:label, @object_name, method, text, objectify_options(options), &block)
end
# See: https://github.com/rails/rails/blob/33d60cb02dcac26d037332410eabaeeb0bdc384c/actionview/lib/action_view/helpers/form_helper.rb#L2280
def label(method, text = nil, options = {}, &block)
render_component(:label, @object_name, method, text, objectify_options(options), &block)
end

def datetime_field(method, options = {})
render_component(
:datetime_local_field, @object_name, method, objectify_options(options)
)
end
alias_method :datetime_locale_field, :datetime_field
def datetime_field(method, options = {})
render_component(
:datetime_local_field, @object_name, method, objectify_options(options)
)
end
alias datetime_locale_field datetime_field

def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
render_component(
:check_box, @object_name, method, checked_value, unchecked_value, objectify_options(options)
)
end
def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
render_component(
:check_box, @object_name, method, checked_value, unchecked_value, objectify_options(options)
)
end

def radio_button(method, tag_value, options = {})
render_component(
:radio_button, @object_name, method, tag_value, objectify_options(options)
)
end
def radio_button(method, tag_value, options = {})
render_component(
:radio_button, @object_name, method, tag_value, objectify_options(options)
)
end

def file_field(method, options = {})
self.multipart = true
render_component(:file_field, @object_name, method, objectify_options(options))
end
def file_field(method, options = {})
self.multipart = true
render_component(:file_field, @object_name, method, objectify_options(options))
end

def submit(value = nil, options = {})
if value.is_a?(Hash)
options = value
value = nil
end
value ||= submit_default_value
render_component(:submit, value, options)
end
def submit(value = nil, options = {})
if value.is_a?(Hash)
options = value
value = nil
end
value ||= submit_default_value
render_component(:submit, value, options)
end

def button(value = nil, options = {}, &block)
if value.is_a?(Hash)
options = value
value = nil
end
value ||= submit_default_value
render_component(:button, value, options, &block)
end
def button(value = nil, options = {}, &block)
if value.is_a?(Hash)
options = value
value = nil
end
value ||= submit_default_value
render_component(:button, value, options, &block)
end

# See: https://github.com/rails/rails/blob/fe76a95b0d252a2d7c25e69498b720c96b243ea2/actionview/lib/action_view/helpers/form_options_helper.rb
def select(method, choices = nil, options = {}, html_options = {}, &block)
render_component(
:select, @object_name, method, choices, objectify_options(options),
@default_html_options.merge(html_options), &block
)
end
# See: https://github.com/rails/rails/blob/fe76a95b0d252a2d7c25e69498b720c96b243ea2/actionview/lib/action_view/helpers/form_options_helper.rb
def select(method, choices = nil, options = {}, html_options = {}, &block)
render_component(
:select, @object_name, method, choices, objectify_options(options),
@default_html_options.merge(html_options), &block
)
end

# rubocop:disable Metrics/ParameterLists
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
render_component(
:collection_select, @object_name, method, collection, value_method, text_method,
objectify_options(options), @default_html_options.merge(html_options)
)
end
# rubocop:disable Metrics/ParameterLists
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
render_component(
:collection_select, @object_name, method, collection, value_method, text_method,
objectify_options(options), @default_html_options.merge(html_options)
)
end

def grouped_collection_select(
method, collection,
group_method, group_label_method, option_key_method, option_value_method,
options = {}, html_options = {}
)
render_component(
:grouped_collection_select, @object_name, method, collection, group_method,
group_label_method, option_key_method, option_value_method,
objectify_options(options), @default_html_options.merge(html_options)
)
end
def grouped_collection_select(
method, collection,
group_method, group_label_method, option_key_method, option_value_method,
options = {}, html_options = {}
)
render_component(
:grouped_collection_select, @object_name, method, collection, group_method,
group_label_method, option_key_method, option_value_method,
objectify_options(options), @default_html_options.merge(html_options)
)
end

def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {},
&block)
render_component(
:collection_check_boxes, @object_name, method, collection, value_method, text_method,
objectify_options(options), @default_html_options.merge(html_options), &block
)
end
def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {},
&block)
render_component(
:collection_check_boxes, @object_name, method, collection, value_method, text_method,
objectify_options(options), @default_html_options.merge(html_options), &block
)
end

def collection_radio_buttons(
method, collection,
value_method, text_method,
options = {}, html_options = {},
&block
)
render_component(
:collection_radio_buttons, @object_name, method, collection, value_method, text_method,
objectify_options(options), @default_html_options.merge(html_options), &block
)
end
# rubocop:enable Metrics/ParameterLists
def collection_radio_buttons(
method, collection,
value_method, text_method,
options = {}, html_options = {},
&block
)
render_component(
:collection_radio_buttons, @object_name, method, collection, value_method, text_method,
objectify_options(options), @default_html_options.merge(html_options), &block
)
end
# rubocop:enable Metrics/ParameterLists

def date_select(method, options = {}, html_options = {})
render_component(
:date_select, @object_name, method,
objectify_options(options), @default_html_options.merge(html_options)
)
end
def date_select(method, options = {}, html_options = {})
render_component(
:date_select, @object_name, method,
objectify_options(options), @default_html_options.merge(html_options)
)
end

def datetime_select(method, options = {}, html_options = {})
render_component(
:datetime_select, @object_name, method,
objectify_options(options), @default_html_options.merge(html_options)
)
end
def datetime_select(method, options = {}, html_options = {})
render_component(
:datetime_select, @object_name, method,
objectify_options(options), @default_html_options.merge(html_options)
)
end

def time_select(method, options = {}, html_options = {})
render_component(
:time_select, @object_name, method,
objectify_options(options), @default_html_options.merge(html_options)
)
end
def time_select(method, options = {}, html_options = {})
render_component(
:time_select, @object_name, method,
objectify_options(options), @default_html_options.merge(html_options)
)
end

def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
render_component(
:time_zone_select, @object_name, method, priority_zones,
objectify_options(options), @default_html_options.merge(html_options)
)
end
def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
render_component(
:time_zone_select, @object_name, method, priority_zones,
objectify_options(options), @default_html_options.merge(html_options)
)
end

if defined?(ActionView::Helpers::Tags::ActionText)
def rich_text_area(method, options = {})
render_component(:rich_text_area, @object_name, method, objectify_options(options))
end
end
if defined?(ActionView::Helpers::Tags::ActionText)
def rich_text_area(method, options = {})
render_component(:rich_text_area, @object_name, method, objectify_options(options))
end
# rubocop:enable Metrics/BlockLength
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/MethodLength
end
# rubocop:enable Metrics/ModuleLength
end
Expand Down
28 changes: 28 additions & 0 deletions lib/view_component/form/helpers/rails_backports.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

module ViewComponent
module Form
module Helpers
module RailsBackports
# Backport field_id from Rails 7.0
if ::Rails::VERSION::MAJOR < 7
Spone marked this conversation as resolved.
Show resolved Hide resolved
def field_id(method_name, *suffixes, namespace: @options[:namespace], index: @index)
object_name = object_name.model_name.singular if object_name.respond_to?(:model_name)

sanitized_object_name = object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").delete_suffix("_")

sanitized_method_name = method_name.to_s.delete_suffix("?")

[
namespace,
sanitized_object_name.presence,
(index unless sanitized_object_name.empty?),
sanitized_method_name,
*suffixes
].tap(&:compact!).join("_")
end
end
end
end
end
end