Packages
petal_components
0.11.4
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/card.ex
defmodule PetalComponents.Card do
use Phoenix.Component
# prop class, :string
# prop variant, :string
# slot default
def card(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:variant, fn -> "basic" end)
~H"""
<div class={Enum.join([
"flex flex-wrap overflow-hidden",
get_variant_classes(@variant),
@class
], " ")}>
<div class="flex flex-col w-full max-w-full bg-white dark:bg-gray-800">
<%= render_slot(@inner_block) %>
</div>
</div>
"""
end
# prop class, :string
# prop aspect_ratio_class, :string
# prop src, :string
def card_media(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:aspect_ratio_class, fn -> "aspect-video" end)
|> assign_new(:src, fn -> nil end)
~H"""
<%= if @src do %>
<img src={@src} class={Enum.join([
"flex-shrink-0 w-full object-cover",
@aspect_ratio_class,
@class
], " ")} />
<% else %>
<div class={Enum.join([
"flex-shrink-0 w-full bg-gray-300 dark:bg-gray-700",
@aspect_ratio_class,
@class
], " ")}></div>
<% end %>
"""
end
# prop class, :string
# prop heading, :string
# prop category, :string
# prop category_color_class, :string
# slot default
def card_content(assigns) do
assigns =
assigns
|> assign_new(:class, fn -> "" end)
|> assign_new(:category_color_class, fn -> "text-primary-600" end)
|> assign_new(:inner_block, fn -> nil end)
|> assign_new(:category, fn -> nil end)
|> assign_new(:heading, fn -> nil end)
~H"""
<div class={Enum.join([
"p-6 flex-1 font-light text-gray-500 text-md",
@class
], " ")}>
<%= if @category do %>
<div class={"mb-3 text-sm font-medium #{@category_color_class}"}>
<%= @category %>
</div>
<% end %>
<%= if @heading do %>
<div class="mb-2 text-xl font-medium text-gray-900 dark:text-gray-300">
<%= @heading %>
</div>
<% end %>
<%= if @inner_block do %>
<%= render_slot(@inner_block) %>
<% end %>
</div>
"""
end
def card_footer(assigns) do
~H"""
<div class="px-6 pb-6">
<%= render_slot(@inner_block) %>
</div>
"""
end
defp get_variant_classes(variant) do
case variant do
"basic" ->
"rounded-lg shadow-lg dark:shadow-2xl"
"outline" ->
"rounded-lg border border-gray-300 dark:border-gray-600"
end
end
end