Packages
petal_components
0.17.7
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
import PetalComponents.Helpers
# 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)
|> assign_rest(~w(class variant)a)
~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
# 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)
|> assign_rest(~w(class aspect_ratio_class src)a)
~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
# 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 dark:text-primary-400" end)
|> assign_new(:inner_block, fn -> nil end)
|> assign_new(:category, fn -> nil end)
|> assign_new(:heading, fn -> nil end)
|> assign_rest(~w(class category_color_class inner_block category heading)a)
~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 %>
<%= if @inner_block do %>
<%= render_slot(@inner_block) %>
<% end %>
</div>
"""
end
def card_footer(assigns) do
assigns =
assigns
|> assign_rest(~w(class)a)
~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