module ViewComponent::SlotableV2
def renders_many(slot_name, callable = nil)
<% end %>
two
<%= component.item(name: "Bar") do %>
<% end %>
One
<%= component.item(name: "Foo") do %>
<%= render_inline(MyComponent.new) do |component| %>
called multiple times to append to the slot.
helper method with the same name as the slot. The method can be
Consumers of the component can set the content of a slot by calling a
= Setting sub-component content
<% end %>
<%= item %>
<%= items.each do |item| %>
helper method with the same name as the slot.
The component's sidecar template can access the slot by calling a
= Rendering sub-components
render_many :items, ItemComponent
# OR
render_many :items, -> (name:) { ItemComponent.new(name: name }
= Example
Registers a collection sub-component
#
def renders_many(slot_name, callable = nil) validate_slot_name(slot_name) singular_name = ActiveSupport::Inflector.singularize(slot_name) # Define setter for singular names # e.g. `renders_many :items` allows fetching all tabs with # `component.tabs` and setting a tab with `component.tab` define_method singular_name do |*args, **kwargs, &block| set_slot(slot_name, *args, **kwargs, &block) end # Instantiates and and adds multiple slots forwarding the first # argument to each slot constructor define_method slot_name do |collection_args = nil, &block| if collection_args.nil? && block.nil? get_slot(slot_name) else collection_args.each do |args| set_slot(slot_name, **args, &block) end end end register_slot(slot_name, collection: true, callable: callable) end