defmodule PetalComponents.Avatar do
use Phoenix.Component
alias PetalComponents.Heroicons
# prop src, :string
# prop size, :string
def avatar(assigns) do
assigns = assigns
|> assign_new(:src, fn -> nil end)
|> assign_new(:size, fn -> "md" end)
|> assign_new(:class, fn -> "" end)
|> assign_new(:name, fn -> nil end)
|> assign_new(:random_color, fn -> false end)
~H"""
<%= if src_blank?(@src) && !@name do %>
<div class={Enum.join([
"inline-block overflow-hidden bg-gray-100 rounded-full",
get_size_classes(@size),
@class
], " ")}>
<Heroicons.Solid.user class="relative w-full h-full text-gray-300 top-[12%] scale-[1.15] transform" />
</div>
<% else %>
<%= if !@src && @name do %>
<div
style={maybe_generate_random_color(@random_color, @name)}
class={Enum.join([
"flex items-center justify-center bg-gray-100 rounded-full font-semibold uppercase text-gray-500",
get_size_classes(@size),
@class,
], " ")}
>
<%= generate_initials(@name) %>
</div>
<% else %>
<img src={@src} class={Enum.join([
"rounded-full",
get_size_classes(@size),
@class
], " ")} />
<% end %>
<% end %>
"""
end
def avatar_group(assigns) do
assigns = assign_new(assigns, :classes, fn -> avatar_group_classes(assigns) end)
~H"""
<div class={@classes}>
<%= for src <- @avatars do %>
<.avatar src={src} size={@size} class="ring-white ring-2" />
<% end %>
</div>
"""
end
defp get_size_classes(size) do
case size do
"xs" -> "w-7 h-7 text-xs"
"sm" -> "w-8 h-8 text-sm"
"md" -> "w-10 h-10 text-md"
"lg" -> "w-12 h-12 text-lg"
"xl" -> "w-14 h-14 text-xl"
end
end
defp avatar_group_classes(opts) do
opts = %{
size: opts[:size] || "md",
class: opts[:class] || ""
}
size_css =
case opts[:size] do
"xs" -> "relative z-0 flex -space-x-2 overflow-hidden"
"sm" -> "relative z-0 flex -space-x-3 overflow-hidden"
"md" -> "relative z-0 flex -space-x-4 overflow-hidden"
"lg" -> "relative z-0 flex -space-x-5 overflow-hidden"
"xl" -> "relative z-0 flex -space-x-6 overflow-hidden"
end
"""
#{opts.class}
#{size_css}
"""
end
defp src_blank?(src) do
(!src || src == "")
end
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