⚠️ Warning
Since the release of Phoenix LiveView 0.18.0 this post is no longer relevant. Instead use dynamic_tag/1. The remainder of this post is left here for the sake of reference.
For a while I've been trying to figure out how to write a higher order component in LiveView that allows you to define the root element. While I wouldn't recommend doing this often, there are infrequent scenarios wherein it might be helpful.
One example is when you're writing a higher order component that's acting as a container. You'd like to make the container remain semantic while also keeping the component reusable.
You can use Phoenix.HTML.Tag.content_tag/3
to achieve this.
def button_as(assigns) do
assigns =
assigns
|> assign_extra_attributes([:as])
~H"""
<%= Phoenix.HTML.Tag.content_tag(@as, render_slot(@inner_block), @extra_attributes) %>
"""
end
def some_component(assigns) do
~H"""
<.button_as as={:label}>Label button</.button_as>
<.button_as as={:button}>Button button</.button_as>
"""
end