Unlike attributes, slot attributes cannot accept the :default option. Passing one will result in a compile warning being issued.
Is there a technical reason for this? I find myself wanting for this feature. Is it just work that hasn’t been done yet or is there a technical issue preventing it? Or is it a bad idea for some reason?
I don’t have an answer to your question around the technical limitations but since a an empty slot is passed in as an empty list I do this:
slot :bar
def foo(assigns) do
~H"""
<%= if Enum.any?(@bar) do %>
<%= render_slot(@bar) %>
<% else %>
Default
<% end %>
"""
end
I literally just did this the other day and would likely use it sparingly (and may try and come up with a different solution that doesn’t need a default). You might want to capture the slot’s empty state in an assign as I haven’t fully wrapped my head around when it’s ok to use a function in heex (and I’m currently seeing some extra data being sent): assigns = assign(assigns, :bar_empty?, Enum.empty?(assigns.bar))
.
2 Likes
This is what I do:
<%= if @bar == [] do %>
Default
<% else %>
<%= render_slot(@bar) %>
<% end %>
I’m talking about slot attributes…
slot :bar do
attr :foo, :string, default: ""
end
Will give a compiler warning because default values on slot attributes aren’t allowed (like they are on regular component attributes).
You can kinda work around it by doing this…
~H"""
<%= for bar <- @bar do %>
<% bar = Map.put_new(bar, :foo, "") %>
...
<%= render_slot(bar) %>
<% end %>
"""
But it’s kinda wonky and not very clear.
1 Like
I misunderstood the question just like you! 
1 Like
Yes, I am concerned it will be slow in practice. We would need to traverse the slot attributes and then every child to set the default. At the root it is not a concern because it is a direct operation on attrs.
4 Likes