Packages
petal_components
4.2.1
4.7.0
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
@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" />
attr(:class, :any, default: nil, doc: "CSS class")
attr(:label, :string, default: nil, doc: "label your heading")
attr(:no_margin, :boolean, default: nil, doc: "removes margin from headings")
attr(:underline, :boolean, default: false, doc: "underlines a heading")
attr(:color_class, :any, default: nil, doc: "adds a color class")
attr(:rest, :global)
slot(:inner_block, required: false)
def h1(assigns) do
~H"""
<h1 class={get_heading_classes("pc-h1", @class, @color_class, @underline, @no_margin)} {@rest}>
{render_slot(@inner_block) || @label}
</h1>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:label, :string, default: nil, doc: "label your heading")
attr(:no_margin, :boolean, default: nil, doc: "removes margin from headings")
attr(:underline, :boolean, default: false, doc: "underlines a heading")
attr(:color_class, :any, default: nil, doc: "adds a color class")
attr(:rest, :global)
slot(:inner_block, required: false)
def h2(assigns) do
~H"""
<h2 class={get_heading_classes("pc-h2", @class, @color_class, @underline, @no_margin)} {@rest}>
{render_slot(@inner_block) || @label}
</h2>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:label, :string, default: nil, doc: "label your heading")
attr(:no_margin, :boolean, default: nil, doc: "removes margin from headings")
attr(:underline, :boolean, default: false, doc: "underlines a heading")
attr(:color_class, :any, default: nil, doc: "adds a color class")
attr(:rest, :global)
slot(:inner_block, required: false)
def h3(assigns) do
~H"""
<h3 class={get_heading_classes("pc-h3", @class, @color_class, @underline, @no_margin)} {@rest}>
{render_slot(@inner_block) || @label}
</h3>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:label, :string, default: nil, doc: "label your heading")
attr(:no_margin, :boolean, default: nil, doc: "removes margin from headings")
attr(:underline, :boolean, default: false, doc: "underlines a heading")
attr(:color_class, :any, default: nil, doc: "adds a color class")
attr(:rest, :global)
slot(:inner_block, required: false)
def h4(assigns) do
~H"""
<h4 class={get_heading_classes("pc-h4", @class, @color_class, @underline, @no_margin)} {@rest}>
{render_slot(@inner_block) || @label}
</h4>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:label, :string, default: nil, doc: "label your heading")
attr(:no_margin, :boolean, default: nil, doc: "removes margin from headings")
attr(:underline, :boolean, default: false, doc: "underlines a heading")
attr(:color_class, :any, default: nil, doc: "adds a color class")
attr(:rest, :global)
slot(:inner_block, required: false)
def h5(assigns) do
~H"""
<h5 class={get_heading_classes("pc-h5", @class, @color_class, @underline, @no_margin)} {@rest}>
{render_slot(@inner_block) || @label}
</h5>
"""
end
defp get_heading_classes(base_classes, custom_classes, color_class, underline, no_margin) do
[
base_classes,
custom_classes,
color_class || "pc-heading--color",
underline && "pc-heading--underline",
!no_margin && "#{base_classes}--margin"
]
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:no_margin, :boolean, default: nil, doc: "removes margin from paragraph")
attr(:rest, :global)
slot(:inner_block, required: false)
def p(assigns) do
~H"""
<p
class={[
"pc-text",
!@no_margin && "pc-p--margin",
@class
]}
{@rest}
>
{render_slot(@inner_block)}
</p>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
def prose(assigns) do
~H"""
<div 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>
"""
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
def ul(assigns) do
~H"""
<ul class={["pc-text", "my-6 ml-6 list-disc [&>li]:mt-2", @class]} {@rest}>
{render_slot(@inner_block)}
</ul>
"""
end
@doc """
Usage:
<.ol>
<li>Item 1</li>
<li>Item 2</li>
</.ol>
"""
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
def ol(assigns) do
~H"""
<ol class={["pc-text", "my-6 ml-6 list-decimal [&>li]:mt-2", @class]} {@rest}>
{render_slot(@inner_block)}
</ol>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
@doc """
A larger, muted introductory paragraph for the top of a page or section.
<.lead>Petal Components is a set of HEEx components for Phoenix.</.lead>
"""
def lead(assigns) do
~H"""
<p class={["pc-lead", @class]} {@rest}>{render_slot(@inner_block)}</p>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
@doc """
A styled blockquote with a left border.
<.blockquote>"This library shipped our marketing site in a weekend."</.blockquote>
"""
def blockquote(assigns) do
~H"""
<blockquote class={["pc-blockquote", @class]} {@rest}>{render_slot(@inner_block)}</blockquote>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
@doc """
Inline code styling for snippets within a sentence.
Run <.inline_code>mix deps.get</.inline_code> to install.
"""
def inline_code(assigns) do
~H"""
<code class={["pc-inline-code", @class]} {@rest}>{render_slot(@inner_block)}</code>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
@doc "Muted secondary text, e.g. a caption or helper line."
def text_muted(assigns) do
~H"""
<p class={["pc-text-muted", @class]} {@rest}>{render_slot(@inner_block)}</p>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
@doc "Slightly larger, emphasised body text."
def text_large(assigns) do
~H"""
<div class={["pc-text-large", @class]} {@rest}>{render_slot(@inner_block)}</div>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
@doc "Small, tight label text."
def text_small(assigns) do
~H"""
<small class={["pc-text-small", @class]} {@rest}>{render_slot(@inner_block)}</small>
"""
end
attr(:class, :any, default: nil, doc: "CSS class")
attr(:rest, :global)
@doc "A horizontal rule with sensible vertical spacing."
def hr(assigns) do
~H"""
<hr class={["pc-hr", @class]} {@rest} />
"""
end
end