Packages
petal_components
4.2.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/avatar.ex
defmodule PetalComponents.Avatar do
use Phoenix.Component
import PetalComponents.Icon
attr(:src, :string, default: nil, doc: "hosted avatar URL")
attr(:alt, :string, default: nil, doc: "alt text for avatar image")
attr(:size, :string, default: "md", values: ["xs", "sm", "md", "lg", "xl"])
attr(:class, :any, default: nil, doc: "CSS class")
attr(:name, :string, default: nil, doc: "name for placeholder initials")
attr(:random_color, :boolean,
default: false,
doc: "generates a random color for placeholder initials avatar"
)
attr(:rest, :global)
def avatar(assigns) do
~H"""
<%= if src_blank?(@src) && !@name do %>
<div
{@rest}
role="img"
aria-label="user avatar"
class={[
"pc-avatar--with-placeholder-icon",
"pc-avatar--#{@size}",
@class
]}
>
<.icon name="hero-user-solid" class="pc-avatar__placeholder-icon" />
</div>
<% else %>
<%= if src_blank?(@src) && @name do %>
<div
{@rest}
style={maybe_generate_random_color(@random_color, @name)}
role="img"
aria-label="user avatar"
class={[
"pc-avatar--with-placeholder-initials",
"pc-avatar--#{@size}",
@class
]}
>
{generate_initials(@name)}
</div>
<% else %>
<img
{@rest}
src={@src}
alt={@alt || @src}
class={[
"pc-avatar--with-image",
"pc-avatar--#{@size}",
@class
]}
/>
<% end %>
<% end %>
"""
end
attr(:size, :string, default: "md", values: ["xs", "sm", "md", "lg", "xl"])
attr(:class, :any, default: nil, doc: "CSS class")
attr(:avatars, :list, default: [], doc: "list of your hosted avatar URLs")
attr(:rest, :global)
def avatar_group(assigns) do
~H"""
<div {@rest} class={["pc-avatar-group--#{@size}", @class]}>
<%= for src <- @avatars do %>
<.avatar src={src} size={@size} class="pc-avatar-group" />
<% end %>
</div>
"""
end
defp src_blank?(src), do: !src || src == ""
defp maybe_generate_random_color(false, _), do: nil
defp maybe_generate_random_color(true, name) do
"background-color: #{generate_color_from_string(name)}; color: white;"
end
defp generate_color_from_string(string) do
a_number =
string
|> String.to_charlist()
|> Enum.reduce(0, fn x, acc -> x + acc end)
"hsl(#{rem(a_number, 360)}, 100%, 35%)"
end
defp generate_initials(name) when is_binary(name) do
word_array = String.split(name)
if length(word_array) == 1 do
List.first(word_array)
|> String.slice(0..1)
|> String.upcase()
else
initial1 = String.first(List.first(word_array))
initial2 = String.first(List.last(word_array))
String.upcase(initial1 <> initial2)
end
end
defp generate_initials(_) do
""
end
end