diff --git a/app/components/view_component/form/collection_check_boxes_component.rb b/app/components/view_component/form/collection_check_boxes_component.rb index 0aefa56..0759695 100644 --- a/app/components/view_component/form/collection_check_boxes_component.rb +++ b/app/components/view_component/form/collection_check_boxes_component.rb @@ -5,6 +5,9 @@ module Form class CollectionCheckBoxesComponent < FieldComponent attr_reader :collection, :value_method, :text_method, :html_options + # IDEA: maybe we can use a slot here to render the collection items? + # renders_many :collection_items + def initialize( # rubocop:disable Metrics/ParameterLists form, object_name, @@ -34,8 +37,7 @@ def call # rubocop:disable Metrics/MethodLength value_method, text_method, options, - html_options, - &content + html_options ).render end @@ -45,6 +47,26 @@ def set_html_options! @html_options[:class] = class_names(html_options[:class], html_class) @html_options.delete(:class) if @html_options[:class].blank? end + + # See: https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/actionview/lib/action_view/helpers/tags/collection_helpers.rb#L89 + def builder + @builder ||= begin + ActionView::Helpers::Tags::CollectionCheckBoxes::CheckBoxBuilder.new(@view_context, object_name, method_name, object, sanitize_attribute_name(value), text, value, input_html_options) + end + end + delegate :translation, to: :builder + + def sanitize_attribute_name(value) + "#{sanitized_method_name}_#{sanitized_value(value)}" + end + + def sanitized_method_name + @sanitized_method_name ||= @method_name.delete_suffix("?") + end + + def sanitized_value(value) + value.to_s.gsub(/[\s.]/, "_").gsub(/[^-[[:word:]]]/, "").downcase + end end end end diff --git a/app/components/view_component/form/collection_radio_buttons_component.rb b/app/components/view_component/form/collection_radio_buttons_component.rb index 07decae..844446c 100644 --- a/app/components/view_component/form/collection_radio_buttons_component.rb +++ b/app/components/view_component/form/collection_radio_buttons_component.rb @@ -34,8 +34,7 @@ def call # rubocop:disable Metrics/MethodLength value_method, text_method, options, - html_options, - &content + html_options ).render end diff --git a/lib/view_component/form/helpers/collection_helpers.rb b/lib/view_component/form/helpers/collection_helpers.rb new file mode 100644 index 0000000..7c198af --- /dev/null +++ b/lib/view_component/form/helpers/collection_helpers.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module ViewComponent + module Form + module Helpers + module CollectionHelpers + # TODO: put common logic between CollectionCheckBoxesComponent and CollectionRadioButtonsComponent here + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index eed8afb..860d283 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -23,6 +23,7 @@ Combustion.initialize!(*modules) do config.logger = ActiveSupport::TaggedLogging.new(Logger.new(nil)) config.log_level = :fatal + config.capture_compatibility_patch_enabled = true end require "generator_spec" diff --git a/spec/view_component/form/collection_check_boxes_component_spec.rb b/spec/view_component/form/collection_check_boxes_component_spec.rb index 5102e16..8b8cf1d 100644 --- a/spec/view_component/form/collection_check_boxes_component_spec.rb +++ b/spec/view_component/form/collection_check_boxes_component_spec.rb @@ -53,6 +53,49 @@ end end + context "with a block" do + let(:block) do + proc do |c| + c.builder.label { c.builder.check_box + c.builder.text } + end + end + + it do + expect(component).to eq_html <<~HTML + + HTML + end + end + + # context "with a block and translation param" do + # let(:block) do + # proc do |component| + # "#{component.translation}".html_safe + # end + # end + + # it do + # expect(component).to eq_html <<~HTML + # + # HTML + # end + # end + + # context "with a block and builder param" do + # let(:block) do + # proc do |component| + # "" \ + # "#{component.builder.translation}".html_safe + # end + # end + + # it do + # expect(component).to eq_html <<~HTML + # + # HTML + # end + # end + include_examples "component with custom html classes", :html_options include_examples "component with custom data attributes", :html_options end