diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c7bab3a8d..9463e56ca 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,6 +9,7 @@ title: Changelog ## main +* Include polymorphic slots in `ViewComponent::Base` by default. * Add per-component config option for stripping newlines from templates before compilation. *Cameron Dutro* diff --git a/docs/guide/slots.md b/docs/guide/slots.md index 4be4df62a..ad2f3c4c5 100644 --- a/docs/guide/slots.md +++ b/docs/guide/slots.md @@ -233,16 +233,14 @@ Slot content can also be set using `#with_content`: _To view documentation for content_areas (deprecated) and the original implementation of Slots (deprecated), see [/content_areas](/content_areas) and [/slots_v1](/slots_v1)._ -## Polymorphic slots (Experimental) +## Polymorphic slots -Polymorphic slots can render one of several possible slots. To use this experimental feature, include `ViewComponent::PolymorphicSlots`. +Polymorphic slots can render one of several possible slots. For example, consider this list item component that can be rendered with either an icon or an avatar visual. The `visual` slot is passed a hash mapping types to slot definitions: ```ruby class ListItemComponent < ViewComponent::Base - include ViewComponent::PolymorphicSlots - renders_one :visual, types: { icon: IconComponent, avatar: lambda { |**system_arguments| diff --git a/lib/view_component/base.rb b/lib/view_component/base.rb index eca04b5bd..136e1a455 100644 --- a/lib/view_component/base.rb +++ b/lib/view_component/base.rb @@ -16,6 +16,7 @@ module ViewComponent class Base < ActionView::Base include ActiveSupport::Configurable include ViewComponent::ContentAreas + include ViewComponent::PolymorphicSlots include ViewComponent::Previewable include ViewComponent::SlotableV2 include ViewComponent::Translatable diff --git a/lib/view_component/polymorphic_slots.rb b/lib/view_component/polymorphic_slots.rb index 8bdba5b6a..867c44193 100644 --- a/lib/view_component/polymorphic_slots.rb +++ b/lib/view_component/polymorphic_slots.rb @@ -5,6 +5,17 @@ module PolymorphicSlots # In older rails versions, using a concern isn't a good idea here because they appear to not work with # Module#prepend and class methods. def self.included(base) + if base != ViewComponent::Base + # :nocov: + location = Kernel.caller_locations(1, 1)[0] + + warn( + "warning: ViewComponent::PolymorphicSlots is now included in ViewComponent::Base by default "\ + "and can be removed from #{location.path}:#{location.lineno}" + ) + # :nocov: + end + base.singleton_class.prepend(ClassMethods) base.include(InstanceMethods) end @@ -45,8 +56,12 @@ def register_polymorphic_slot(slot_name, types, collection:) "#{slot_name}_#{poly_type}" end - # Deprecated: Will be removed in 3.0 define_method(setter_name) do |*args, &block| + ViewComponent::Deprecation.warn( + "polymorphic slot setters like `#{setter_name}` are deprecated and will be removed in"\ + "ViewComponent v3.0.0.\n\nUse `with_#{setter_name}` instead." + ) + set_polymorphic_slot(slot_name, poly_type, *args, &block) end ruby2_keywords(setter_name.to_sym) if respond_to?(:ruby2_keywords, true) diff --git a/test/sandbox/app/components/polymorphic_slot_component.rb b/test/sandbox/app/components/polymorphic_slot_component.rb index 3324bfd72..b4ced91c7 100644 --- a/test/sandbox/app/components/polymorphic_slot_component.rb +++ b/test/sandbox/app/components/polymorphic_slot_component.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class PolymorphicSlotComponent < ViewComponent::Base - include ViewComponent::PolymorphicSlots - renders_one :header, types: { standard: lambda { |&block| content_tag(:div, class: "standard", &block) }, special: lambda { |&block| content_tag(:div, class: "special", &block) }