Packages
petal_components
0.18.2
4.6.2
4.6.1
4.6.0
4.5.0
4.4.0
4.3.0
4.2.1
4.2.0
4.1.2
4.1.1
4.1.0
4.0.12
4.0.11
4.0.10
4.0.6
4.0.5
4.0.4
4.0.3
4.0.1
3.2.2
3.2.1
3.2.0
3.1.0
3.0.2
3.0.1
3.0.0
2.9.3
2.9.2
retired
2.9.1
retired
2.9.0
retired
2.8.4
2.8.3
2.8.2
2.8.1
2.8.0
2.7.4
2.7.3
2.7.2
2.7.1
2.7.0
2.6.1
2.6.0
2.5.2
2.5.1
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.0
2.2.1
2.2.0
2.1.2
2.1.1
2.1.0
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.9.3
1.9.2
1.9.1
1.9.0
1.8.0
1.7.1
1.7.0
1.6.2
1.6.1
1.6.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.14
1.2.13
1.2.12
1.2.11
1.2.10
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.19.10
0.19.9
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.7
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.15.0
0.14.1
0.14.0
0.13.7
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.8
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.0
Shadcn-style Phoenix LiveView components that AI assistants can actually use. Pair with the MCP server so AI coding tools can inspect the real component API.
Current section
Files
Jump to
Current section
Files
lib/petal_components/typography.ex
defmodule PetalComponents.Typography do
use Phoenix.Component
import PetalComponents.Helpers
@moduledoc """
Everything related to text. Headings, paragraphs and links
"""
# <.h1>Heading</.h1>
# <.h1 label="Heading" />
# <.h1 label="Heading" class="mb-10" color_class="text-blue-500" />
# prop label, :string
# prop class, :string
# slot default
def h1(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:rest, fn -> drop_heading_props(assigns) end)
~H"""
<h1 class={get_heading_classes("text-4xl font-extrabold leading-10 sm:text-5xl sm:tracking-tight lg:text-6xl", assigns)} {@rest}>
<%= if assigns[:label] do %>
<%= @label %>
<% else %>
<%= render_slot(@inner_block) %>
<% end %>
</h1>
"""
end
def h2(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:rest, fn -> drop_heading_props(assigns) end)
~H"""
<h2 class={get_heading_classes("text-2xl sm:text-3xl font-extrabold leading-10", assigns)} {@rest}>
<%= if assigns[:label] do %>
<%= @label %>
<% else %>
<%= render_slot(@inner_block) %>
<% end %>
</h2>
"""
end
def h3(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:rest, fn -> drop_heading_props(assigns) end)
~H"""
<h3 class={get_heading_classes("text-xl sm:text-2xl font-bold leading-7", assigns)} {@rest}>
<%= if assigns[:label] do %>
<%= @label %>
<% else %>
<%= render_slot(@inner_block) %>
<% end %>
</h3>
"""
end
def h4(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:rest, fn -> drop_heading_props(assigns) end)
~H"""
<h4 class={get_heading_classes("text-lg font-bold leading-6", assigns)} {@rest}>
<%= if assigns[:label] do %>
<%= @label %>
<% else %>
<%= render_slot(@inner_block) %>
<% end %>
</h4>
"""
end
def h5(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:rest, fn -> drop_heading_props(assigns) end)
~H"""
<h5 class={get_heading_classes("text-lg font-medium leading-6", assigns)} {@rest}>
<%= if assigns[:label] do %>
<%= @label %>
<% else %>
<%= render_slot(@inner_block) %>
<% end %>
</h5>
"""
end
defp get_heading_classes(base_classes, assigns) do
custom_classes = assigns[:class]
color_classes = assigns[:color_class] || "text-gray-900 dark:text-white"
underline_classes = if assigns[:underline], do: " border-b border-gray-200 pb-2", else: ""
margin_classes = if assigns[:no_margin], do: "", else: "mb-3"
build_class([base_classes, custom_classes, color_classes, underline_classes, margin_classes])
end
defp drop_heading_props(assigns) do
assigns_to_attributes(assigns, ~w(class label color_class underline no_margin)a)
end
def p(assigns) do
assigns =
assign_new(assigns, :class, fn -> "" end)
|> assign_new(:rest, fn ->
assigns_to_attributes(assigns, ~w(class)a)
end)
~H"""
<p class={build_class([text_base_class(), "mb-2", @class])} {@rest}>
<%= render_slot(@inner_block) %>
</p>
"""
end
defp text_base_class(), do: "leading-5 text-gray-600 dark:text-gray-400"
def prose(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:rest, fn ->
assigns_to_attributes(assigns, ~w(class)a)
end)
~H"""
<div class={build_class(["prose dark:prose-invert", @class])} {@rest}>
<%= render_slot(@inner_block) %>
</div>
"""
end
@doc """
Usage:
<.ul>
<li>Item 1</li>
<li>Item 2</li>
</.ul>
"""
def ul(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:rest, fn ->
assigns_to_attributes(assigns, ~w(class)a)
end)
~H"""
<ul class={build_class([text_base_class(), "list-disc list-inside", @class])} {@rest}>
<%= render_slot(@inner_block) %>
</ul>
"""
end
@doc """
Usage:
<.ol>
<li>Item 1</li>
<li>Item 2</li>
</.ol>
"""
def ol(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_rest(~w(class)a)
~H"""
<ol class={build_class([text_base_class(), "list-decimal list-inside", @class])} {@rest}>
<%= render_slot(@inner_block) %>
</ol>
"""
end
end