From 1514d60328af6c1f0bb4905b8a685de39910c74f Mon Sep 17 00:00:00 2001 From: Joel Warrington Date: Thu, 4 Apr 2024 21:04:09 -0600 Subject: [PATCH] Add gem configuration, with base component customization --- .../view_component/form/base_component.rb | 2 +- lib/view_component/form.rb | 10 ++++++++++ lib/view_component/form/configuration.rb | 13 +++++++++++++ .../app/components/application_form_component.rb | 4 ++++ .../config/initializers/view_component_form.rb | 5 +++++ spec/view_component/form/base_component_spec.rb | 8 ++++++++ spec/view_component/form/builder_spec.rb | 8 ++++++++ spec/view_component/form/configuration_spec.rb | 11 +++++++++++ spec/view_component/form_spec.rb | 4 ++++ 9 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 lib/view_component/form/configuration.rb create mode 100644 spec/internal/app/components/application_form_component.rb create mode 100644 spec/internal/config/initializers/view_component_form.rb create mode 100644 spec/view_component/form/configuration_spec.rb diff --git a/app/components/view_component/form/base_component.rb b/app/components/view_component/form/base_component.rb index b2206141..e2ad2961 100644 --- a/app/components/view_component/form/base_component.rb +++ b/app/components/view_component/form/base_component.rb @@ -2,7 +2,7 @@ module ViewComponent module Form - class BaseComponent < ViewComponent::Base + class BaseComponent < ViewComponent::Form.configuration.parent_component.constantize class << self attr_accessor :default_options end diff --git a/lib/view_component/form.rb b/lib/view_component/form.rb index 438d26b9..afe85ba3 100644 --- a/lib/view_component/form.rb +++ b/lib/view_component/form.rb @@ -1,10 +1,20 @@ # frozen_string_literal: true require "view_component" +require_relative "form/configuration" require "zeitwerk" module ViewComponent module Form + class << self + def configuration + @configuration ||= Configuration.new + end + + def configure + yield configuration + end + end end end diff --git a/lib/view_component/form/configuration.rb b/lib/view_component/form/configuration.rb new file mode 100644 index 00000000..9f9d0084 --- /dev/null +++ b/lib/view_component/form/configuration.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ViewComponent + module Form + class Configuration + attr_accessor :parent_component + + def initialize + @parent_component = "ViewComponent::Base" + end + end + end +end diff --git a/spec/internal/app/components/application_form_component.rb b/spec/internal/app/components/application_form_component.rb new file mode 100644 index 00000000..b6ded24d --- /dev/null +++ b/spec/internal/app/components/application_form_component.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +class ApplicationFormComponent < ViewComponent::Base +end diff --git a/spec/internal/config/initializers/view_component_form.rb b/spec/internal/config/initializers/view_component_form.rb new file mode 100644 index 00000000..36203470 --- /dev/null +++ b/spec/internal/config/initializers/view_component_form.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +ViewComponent::Form.configure do |config| + config.parent_component = "ApplicationFormComponent" +end diff --git a/spec/view_component/form/base_component_spec.rb b/spec/view_component/form/base_component_spec.rb index afb75929..c90de8fa 100644 --- a/spec/view_component/form/base_component_spec.rb +++ b/spec/view_component/form/base_component_spec.rb @@ -46,4 +46,12 @@ def name it { expect(component.object_errors?).to be(false) } end end + + describe "parent_component" do + subject { described_class } + + context "without configured parent_component" do + it { is_expected.to be < ViewComponent::Base } + end + end end diff --git a/spec/view_component/form/builder_spec.rb b/spec/view_component/form/builder_spec.rb index 3d1c2f6f..a912de81 100644 --- a/spec/view_component/form/builder_spec.rb +++ b/spec/view_component/form/builder_spec.rb @@ -192,4 +192,12 @@ it { expect(builder.send(:validation_context)).to eq(:create) } end end + + describe "base component parent" do + subject(:field) { described_class.new(object_name, object, template, options).send(:component_klass, :text_field) } + + it "is configured via initializer" do + expect(field.ancestors).to include(ApplicationFormComponent) + end + end end diff --git a/spec/view_component/form/configuration_spec.rb b/spec/view_component/form/configuration_spec.rb new file mode 100644 index 00000000..fb4b0387 --- /dev/null +++ b/spec/view_component/form/configuration_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +RSpec.describe ViewComponent::Form::Configuration do + subject(:configuration) { described_class.new } + + describe "defaults" do + it do + expect(configuration).to have_attributes(parent_component: "ViewComponent::Base") + end + end +end diff --git a/spec/view_component/form_spec.rb b/spec/view_component/form_spec.rb index 8ba29782..3a48a788 100644 --- a/spec/view_component/form_spec.rb +++ b/spec/view_component/form_spec.rb @@ -5,6 +5,10 @@ expect(ViewComponent::Form::VERSION).not_to be_nil end + it "is configurable" do + expect { |block| described_class.configure(&block) }.to yield_with_args(ViewComponent::Form::Configuration) + end + if ENV.fetch("VIEW_COMPONENT_FORM_USE_ACTIONTEXT", "false") == "true" it "loads ActionText" do expect(defined?(ActionView::Helpers::Tags::ActionText)).to eq("constant")