A project I am working on required adding breadcrumb navigation. If you’re not familiar with the term, it is a list of links usually at the top of the page that represents how you got to the page you are on, like this:
There were two challenges. First, making this into a reusable component, since it would exist on most pages.
The end result looked like this in the LiveView:
<.breadcrumb links={[
{"Feature Flags", "/flags"},
{"Projects", "/flags/projects"},
{"Environments", "/flags/projects/#{@project_id}/environments"},
{"Flags", "/flags/projects/#{@project_id}/environments/#{@environment_id}/flags"}
]} />
A tidy list of labels and links for the breadcrumbs. That uses a component defined:
attr :links, :any, required: true, doc: "two-tuple containing a label and a link"
def breadcrumb(assigns) do
~H"""
<ul class="mb-4 text-sm">
<li :for={{label, link} <- @links} class="inline-block pr-1"><a href={link} class="hover:underline pr-1"><%= label %></a></li>
</ul>
"""
end
That gave me a nice inline list of links. But, one thing most breadcrumbs have is a visual separator. In the screenshot, it is single right angle quote.
To add that, I learned that TailwindCSS has great support for psuedo classes. In this case, what I wanted to do was inject content after each link except the final one. The resulting code looks like this:
<li :for={{label, link} <- @links} class="after:content-['›'] inline-block pr-1 last-of-type:after:content-['']">
...