portfolio/lib/portfolio_web/components/custom_components.ex

136 lines
3.0 KiB
Elixir

defmodule PortfolioWeb.CustomComponents do
use Phoenix.Component
import PortfolioWeb.CoreComponents
@doc """
Renders an anchor tag that opens a new tab.
## Examples
<.link_blank href="/files/tagless-final-parsing/kiselyov-interpreters.pdf">
PDF
</.link_blank>,
"""
attr :href, :string, required: true
slot :inner_block, required: true
def link_blank(assigns) do
~H"""
<a target="_blank" href={@href}>
<%= render_slot(@inner_block) %>
</a>
"""
end
@doc """
Renders a project description.
"""
attr :title, :string, required: true
attr :href, :string, required: true
attr :date, :string, required: true
slot :inner_block, required: true
def project(assigns) do
~H"""
<div>
<a target="_blank" href={@href} class="pr-1 font-bold text-cyan-500"><%= @title %></a>
<span class="text-slate-400 text-sm"><%= @date %></span>
<p class="pt-1">
<%= render_slot(@inner_block) %>
</p>
</div>
"""
end
@doc """
Renders a blog description.
"""
attr :title, :string, required: true
attr :href, :string, required: true
attr :date, :string, required: true
slot :inner_block, required: true
def blog(assigns) do
~H"""
<div>
<.link navigate={@href} class="pr-1 font-bold text-cyan-500"><%= @title %></.link>
<span class="text-slate-400 text-sm"><%= @date %></span>
<p class="pt-1">
<%= render_slot(@inner_block) %>
</p>
</div>
"""
end
@doc """
Renders an informational admonition.
"""
slot :inner_block, required: true
def info(assigns) do
~H"""
<div class="bg-info flex flex-col p-4 gap-2" role="alert">
<div class="flex items-center gap-1">
<.icon name="hero-information-circle" />
<strong>Info</strong>
</div>
<%= render_slot(@inner_block) %>
</div>
"""
end
@doc """
Renders a tip admonition.
"""
slot :inner_block, required: true
def tip(assigns) do
~H"""
<div class="bg-tip flex flex-col p-4 gap-2" role="alert">
<div class="flex items-center gap-1">
<.icon name="hero-pencil" />
<strong>Tip</strong>
</div>
<%= render_slot(@inner_block) %>
</div>
"""
end
@doc """
Renders a warning admonition.
"""
slot :inner_block, required: true
def warning(assigns) do
~H"""
<div class="bg-warning flex flex-col p-4 gap-2" role="alert">
<div class="flex items-center gap-1">
<.icon name="hero-exclamation-triangle" />
<strong>Warning</strong>
</div>
<%= render_slot(@inner_block) %>
</div>
"""
end
@doc """
Renders an accordion.
"""
attr :header, :string, required: true
slot :inner_block, required: true
def accordion(assigns) do
~H"""
<details class="border border-dashed border-color-[#rgba(155, 155, 155, 0.8)] p-4">
<summary>
<strong><%= @header %></strong>
</summary>
<div class="pt-6">
<%= render_slot(@inner_block) %>
</div>
</details>
"""
end
end