Packages
petal_components
4.4.0
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/rating.ex
defmodule PetalComponents.Rating do
use Phoenix.Component
attr(:rating, :any, default: 0, doc: "The rating to display (integer or float)")
attr(:round_to_nearest_half, :boolean,
default: true,
doc: "Whether to round the rating to the nearest half star (eg. 3.3 -> 3.5"
)
attr(:total, :integer, default: 5, doc: "The total number of stars to display")
attr(:class, :any, default: nil, doc: "Any additional CSS classes for the rating wrapper")
attr(:star_class, :any,
default: nil,
doc:
"Any additional CSS classes for the individual stars. Eg. you could change the size of the stars with 'h-10 w-10'"
)
attr(:include_label, :boolean,
default: false,
doc: "Whether to include an automatically generated rating label"
)
attr(:label_class, :any,
default: nil,
doc: "Any additional CSS classes for the rating label"
)
def rating(assigns) do
assigns =
assigns
|> assign(:rating_as_float, to_float(assigns.rating))
~H"""
<div class={["pc-rating__wrapper", @class]}>
<%= for i <- 1..@total do %>
<.rating_star
class={@star_class}
type={calculate_type(i, @rating_as_float, @round_to_nearest_half)}
/>
<% end %>
<%= if @include_label do %>
<span class={["pc-rating__label", @label_class]}>
{@rating_as_float} out of {@total}
</span>
<% end %>
</div>
"""
end
defp to_float(value) when is_integer(value), do: value + 0.0
defp to_float(value) when is_float(value), do: value
defp round_to_half(number) do
round(number * 2) / 2
end
defp calculate_type(current_star, rating, round_to_nearest_half) do
maybe_rounded = if round_to_nearest_half, do: round_to_half(rating), else: rating
if current_star <= trunc(rating) do
:filled
else
case maybe_rounded - (current_star - 1) do
n when n >= 0.5 and n < 1 -> :half
_ -> :empty
end
end
end
attr :class, :any, default: nil, doc: "Any additional CSS classes for the star"
attr :type, :atom, default: :empty, doc: "The type of star to display"
def rating_star(%{type: :empty} = assigns) do
~H"""
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class={["pc-rating__star--empty", @class]}
>
<path fill="none" d="M0 0h24v24H0z" /><path d="M12 18.26l-7.053 3.948 1.575-7.928L.587 8.792l8.027-.952L12 .5l3.386 7.34 8.027.952-5.935 5.488 1.575 7.928L12 18.26zm0-2.292l4.247 2.377-.949-4.773 3.573-3.305-4.833-.573L12 5.275l-2.038 4.42-4.833.572 3.573 3.305-.949 4.773L12 15.968z" />
</svg>
"""
end
def rating_star(%{type: :filled} = assigns) do
~H"""
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class={["pc-rating__star--filled", @class]}
>
<path fill="none" d="M0 0h24v24H0z" /><path d="M12 18.26l-7.053 3.948 1.575-7.928L.587 8.792l8.027-.952L12 .5l3.386 7.34 8.027.952-5.935 5.488 1.575 7.928z" />
</svg>
"""
end
def rating_star(%{type: :half} = assigns) do
~H"""
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class={["pc-rating__star--half", @class]}
>
<path fill="none" d="M0 0h24v24H0z" /><path d="M12 15.968l4.247 2.377-.949-4.773 3.573-3.305-4.833-.573L12 5.275v10.693zm0 2.292l-7.053 3.948 1.575-7.928L.587 8.792l8.027-.952L12 .5l3.386 7.34 8.027.952-5.935 5.488 1.575 7.928L12 18.26z" />
</svg>
"""
end
end