1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
---
nav_exclude: true
---
# Slots V1 (deprecated)
_Slots V1 is now deprecated and will be removed in 3.0. Please migrate to [Slots V2](/guide/slots.html)_
Slots enable multiple blocks of content to be passed to a single ViewComponent, reducing the need for sub-components (for example ModalHeader, ModalBody).
By default, slots can be rendered once per component. They provide an accessor with the name of the slot (`#header`) that returns an instance of `ViewComponent::Slot`, etc.
Slots declared with `collection: true` can be rendered multiple times. They provide an accessor with the pluralized name of the slot (`#rows`), which is an Array of `ViewComponent::Slot` instances.
To learn more about the design of the Slots API, see [#348](https://github.com/viewcomponent/view_component/pull/348) and [#325](https://github.com/viewcomponent/view_component/discussions/325).
## Defining Slots
Slots are defined by `with_slot`:
`with_slot :header`
To define a collection slot, add `collection: true`:
`with_slot :row, collection: true`
To define a slot with a custom Ruby class, pass `class_name`:
`with_slot :body, class_name: 'BodySlot'`
_Note: Slot classes must be subclasses of `ViewComponent::Slot`._
## Example ViewComponent with Slots
```ruby
# box_component.rb
class BoxComponent < ViewComponent::Base
include ViewComponent::Slotable
with_slot :body, :footer
with_slot :header, class_name: "Header"
with_slot :row, collection: true, class_name: "Row"
class Header < ViewComponent::Slot
def initialize(classes: "")
@classes = classes
end
def classes
"Box-header #{@classes}"
end
end
class Row < ViewComponent::Slot
def initialize(theme: :gray)
@theme = theme
end
def theme_class_name
case @theme
when :gray
"Box-row--gray"
when :hover_gray
"Box-row--hover-gray"
when :yellow
"Box-row--yellow"
when :blue
"Box-row--blue"
when :hover_blue
"Box-row--hover-blue"
else
"Box-row--gray"
end
end
end
end
```
```erb
<%# box_component.html.erb %>
<div class="Box">
<% if header %>
<div class="<%= header.classes %>">
<%= header.content %>
</div>
<% end %>
<% if body %>
<div class="Box-body">
<%= body.content %>
</div>
<% end %>
<% if rows.any? %>
<ul>
<% rows.each do |row| %>
<li class="Box-row <%= row.theme_class_name %>">
<%= row.content %>
</li>
<% end %>
</ul>
<% end %>
<% if footer %>
<div class="Box-footer">
<%= footer.content %>
</div>
<% end %>
</div>
```
`# index.html.erb`
```erb
<%= render(BoxComponent.new) do |component| %>
<% component.slot(:header, classes: "my-class-name") do %>
This is my header!
<% end %>
<% component.slot(:body) do %>
This is the body.
<% end %>
<% component.slot(:row) do %>
Row one
<% end %>
<% component.slot(:row, theme: :yellow) do %>
Yellow row
<% end %>
<% component.slot(:footer) do %>
This is the footer.
<% end %>
<% end %>
```
|