Trying to understand html.heex Phoenix component Slots

I having difficulty understanding what’s happening here:

slot :inner_block, required: true

def button(assigns) do
  ~H"""
  <button>
    {render_slot(@inner_block)}
  </button>
  """
end

The expression render_slot(@inner_block) renders the HEEx content. You can invoke this function component like so:

<.button>
  This renders <strong>inside</strong> the button!
</.button>

Which renders the following HTML:

<button>
  This renders <strong>inside</strong> the button!
</button>

Inner block is not used as a colonned(?) tag. Yet in another example

Slot attributes

Unlike the default slot, it is possible to pass a named slot multiple pieces of HEEx content. Named slots can also accept attributes, defined by passing a block to the slot/3 macro. If multiple pieces of content are passed, render_slot/2 will merge and render all the values.

Below is a table component illustrating multiple named slots with attributes:

slot :column, doc: "Columns with column labels" do
  attr :label, :string, required: true, doc: "Column label"
end

attr :rows, :list, default: []

def table(assigns) do
  ~H"""
  <table>
    <tr>
      <th :for={col <- @column}>{col.label}</th>
    </tr>
    <tr :for={row <- @rows}>
      <td :for={col <- @column}>{render_slot(col, row)}</td>
    </tr>
  </table>
  """
end

You can invoke this function component like so:

<.table rows={[%{name: "Jane", age: "34"}, %{name: "Bob", age: "51"}]}>
  <:column :let={user} label="Name">
    {user.name}
  </:column>
  <:column :let={user} label="Age">
    {user.age}
  </:column>
</.table>

…we have slots in the colon tag form.

inner_block is basically the “default slot”, its whatever is within <.button> and </.button> that’s not inside a named slot (colonned tag, as you put it)

4 Likes

Opps can’t mark as solved as this is under chat and discussion. Apologies.

EDIT: Thanks Aston

You’re on the right track! inner_block is the default slot, capturing content inside the component. Named slots like :column allow multiple pieces of HEEx content with attributes. Hope that helps!

1 Like