diff --git a/lib/view_component/base.rb b/lib/view_component/base.rb index 9996807e2..88e6db55d 100644 --- a/lib/view_component/base.rb +++ b/lib/view_component/base.rb @@ -103,6 +103,13 @@ def render_in(view_context, &block) @__vc_content_evaluated = false @__vc_render_in_block = block + if self.class.send(:__vc_content_is_a_slot?) + @__vc_content_evaluated = true + if __vc_render_in_block_provided? + view_context.capture(self, &@__vc_render_in_block) + end + end + before_render if render? @@ -549,6 +556,10 @@ def render_template_for(variant = nil, format = nil) child.instance_variable_set(:@__vc_ancestor_calls, vc_ancestor_calls) end + if defined?(@__vc_content_is_a_slot) + child.instance_variable_set(:@__vc_content_is_a_slot, @__vc_content_is_a_slot) + end + super end @@ -687,6 +698,19 @@ def initialize_parameters def provided_collection_parameter @provided_collection_parameter ||= nil end + + def __vc_content_is_a_slot? + defined?(@__vc_content_is_a_slot) && @__vc_content_is_a_slot + end + + def content_is_a_slot! + @__vc_content_is_a_slot = true + renders_one :content + end + + def do_not_use_content_as_a_slot! + @__vc_content_is_a_slot = false + end end ActiveSupport.run_load_hooks(:view_component, self) diff --git a/lib/view_component/slotable.rb b/lib/view_component/slotable.rb index c537d4828..320d0a4ff 100644 --- a/lib/view_component/slotable.rb +++ b/lib/view_component/slotable.rb @@ -298,8 +298,10 @@ def define_slot(slot_name, collection:, callable:) end def validate_plural_slot_name(slot_name) - if RESERVED_NAMES[:plural].include?(slot_name.to_sym) - raise ReservedPluralSlotNameError.new(name, slot_name) + if slot_name.to_sym == :contents && !__vc_content_is_a_slot? + if RESERVED_NAMES[:plural].include?(slot_name.to_sym) + raise ReservedPluralSlotNameError.new(name, slot_name) + end end raise_if_slot_name_uncountable(slot_name) @@ -309,12 +311,12 @@ def validate_plural_slot_name(slot_name) end def validate_singular_slot_name(slot_name) - if slot_name.to_sym == :content + if slot_name.to_sym == :content && !__vc_content_is_a_slot? raise ContentSlotNameError.new(name) - end - - if RESERVED_NAMES[:singular].include?(slot_name.to_sym) - raise ReservedSingularSlotNameError.new(name, slot_name) + elsif !__vc_content_is_a_slot? + if RESERVED_NAMES[:singular].include?(slot_name.to_sym) + raise ReservedSingularSlotNameError.new(name, slot_name) + end end raise_if_slot_conflicts_with_call(slot_name) diff --git a/test/sandbox/app/components/content_as_slot_component.html.erb b/test/sandbox/app/components/content_as_slot_component.html.erb new file mode 100644 index 000000000..b784aa225 --- /dev/null +++ b/test/sandbox/app/components/content_as_slot_component.html.erb @@ -0,0 +1,5 @@ +