module ViewComponent::Slotable

def renders_one(slot_name, callable = nil)

<%= render_inline(MyComponent.new.with_header_content("Foo")) %>

on the component instance.
Additionally, content can be set by calling `with_SLOT_NAME_content`

<% end %>
<% end %>

Bar


<% component.with_header(classes: "Foo") do %>
<%= render_inline(MyComponent.new) do |component| %>

helper method with the same name as the slot prefixed with `with_`.
Consumers of the component can render a sub-component by calling a

= Setting sub-component content


<% end %>
My header title
<%= header do %>



helper method with the same name as the sub-component.
The component's sidecar template can access the sub-component by calling a

= Rendering sub-component content


<%= content %>


and has the following template:

end
end
@classes = classes
def initialize(classes:)
class HeaderComponent < ViewComponent::Base

where `HeaderComponent` is defined as:

renders_one :header, HeaderComponent

# OR

end
HeaderComponent.new(classes: classes)
renders_one :header -> (classes:) do

= Example

Registers a sub-component
#

def renders_one(slot_name, callable = nil)
  validate_singular_slot_name(slot_name)
  if callable.is_a?(Hash) && callable.key?(:types)
    register_polymorphic_slot(slot_name, callable[:types], collection: false)
  else
    validate_plural_slot_name(ActiveSupport::Inflector.pluralize(slot_name).to_sym)
    setter_method_name = :"with_#{slot_name}"
    define_method setter_method_name do |*args, &block|
      set_slot(slot_name, nil, *args, &block)
    end
    ruby2_keywords(setter_method_name) if respond_to?(:ruby2_keywords, true)
    self::GeneratedSlotMethods.define_method slot_name do
      get_slot(slot_name)
    end
    self::GeneratedSlotMethods.define_method :"#{slot_name}?" do
      get_slot(slot_name).present?
    end
    define_method :"with_#{slot_name}_content" do |content|
      send(setter_method_name) { content.to_s }
      self
    end
    register_slot(slot_name, collection: false, callable: callable)
  end
end