Packages
petal_components
0.19.4
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
import PetalComponents.Helpers
attr(:class, :string, default: "", doc: "CSS class")
attr(:variant, :string, default: "basic", values: ["basic", "outline"])
attr(:rest, :global)
slot(:inner_block, required: false)
def card(assigns) do
~H"""
<div
{@rest}
class={
build_class([
"flex flex-wrap overflow-hidden bg-white dark:bg-gray-800",
get_variant_classes(@variant),
@class
])
}
>
<div class="flex flex-col w-full max-w-full">
<%= render_slot(@inner_block) %>
</div>
</div>
"""
end
attr(:aspect_ratio_class, :string, default: "aspect-video", doc: "aspect ratio class")
attr(:src, :string, default: nil, doc: "hosted image URL")
attr(:class, :string, default: "", doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
def card_media(assigns) do
~H"""
<%= if @src do %>
<img
{@rest}
src={@src}
class={
build_class(
[
"flex-shrink-0 w-full object-cover",
@aspect_ratio_class,
@class
],
" "
)
}
/>
<% else %>
<div
{@rest}
class={
build_class([
"flex-shrink-0 w-full bg-gray-300 dark:bg-gray-700",
@aspect_ratio_class,
@class
])
}
>
</div>
<% end %>
"""
end
attr(:heading, :string, default: nil, doc: "creates a heading")
attr(:category, :string, default: nil, doc: "creates a category")
attr(:category_color_class, :string,
default: "text-primary-600 dark:text-primary-400",
doc: "sets a category color class"
)
attr(:class, :string, default: "", doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
def card_content(assigns) do
~H"""
<div
{@rest}
class={
build_class([
"p-6 flex-1 font-light text-gray-500 dark:text-gray-400 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 %>
<%= render_slot(@inner_block) || @label %>
</div>
"""
end
attr(:class, :string, default: "", doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
def card_footer(assigns) do
~H"""
<div {@rest} 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 border border-gray-200 dark:border-none"
"outline" ->
"rounded-lg border border-gray-300 dark:border-gray-600"
end
end
end