Skip to content

Commit

Permalink
Include polymorphic slots behavior by default (#1401)
Browse files Browse the repository at this point in the history
  • Loading branch information
camertron authored Jun 22, 2022
1 parent 361c890 commit 1a2e39d
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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*
Expand Down
6 changes: 2 additions & 4 deletions docs/guide/slots.md
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down
1 change: 1 addition & 0 deletions lib/view_component/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 16 additions & 1 deletion lib/view_component/polymorphic_slots.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions test/sandbox/app/components/polymorphic_slot_component.rb
Original file line number Diff line number Diff line change
@@ -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) }
Expand Down

0 comments on commit 1a2e39d

Please sign in to comment.