Packages
petal_components
0.19.3
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/tabs.ex
defmodule PetalComponents.Tabs do
use Phoenix.Component
alias PetalComponents.Link
import PetalComponents.Helpers
attr(:underline, :boolean, default: false, doc: "underlines your tabs")
attr(:class, :string, default: "", doc: "CSS class")
attr(:rest, :global)
slot(:inner_block, required: false)
def tabs(assigns) do
~H"""
<div
{@rest}
class={
build_class(
[
"flex gap-x-8 gap-y-2",
if(@underline, do: "border-b border-gray-200 dark:border-gray-600", else: ""),
@class
],
" "
)
}
>
<%= render_slot(@inner_block) %>
</div>
"""
end
attr(:class, :string, default: "", doc: "CSS class")
attr(:label, :string, default: nil, doc: "labels your tab")
attr(:link_type, :string,
default: "a",
values: ["a", "live_patch", "live_redirect"]
)
attr(:to, :string, default: nil, doc: "link path")
attr(:number, :integer, default: nil, doc: "indicates a number next to your tab")
attr(:underline, :boolean, default: false, doc: "underlines your your tab")
attr(:is_active, :boolean, default: false, doc: "indicates the current tab")
attr(:rest, :global, include: ~w(method download hreflang ping referrerpolicy rel target type))
slot(:inner_block, required: false)
def tab(assigns) do
~H"""
<Link.a
link_type={@link_type}
label={@label}
to={@to}
class={get_tab_class(@is_active, @underline) <> @class}
{@rest}
>
<%= if @number do %>
<%= render_slot(@inner_block) || @label %>
<span class={get_tab_number_class(@is_active, @underline)}>
<%= @number %>
</span>
<% else %>
<%= render_slot(@inner_block) || @label %>
<% end %>
</Link.a>
"""
end
# Pill CSS
defp get_tab_class(is_active, false) do
base_classes = "whitespace-nowrap px-3 py-2 flex font-medium items-center text-sm rounded-md"
active_classes =
if is_active,
do: "bg-primary-100 dark:bg-gray-800 text-primary-600 dark:text-primary-500",
else:
"text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 dark:text-gray-400 dark:hover:bg-gray-800 hover:bg-gray-100"
build_class([base_classes, active_classes])
end
# Underline CSS
defp get_tab_class(is_active, underline) do
base_classes = "whitespace-nowrap flex items-center py-3 px-3 border-b-2 font-medium text-sm"
active_classes =
if is_active,
do: "border-primary-500 text-primary-600 dark:text-primary-500 dark:border-primary-500",
else:
"border-transparent text-gray-500 dark:hover:text-gray-300 dark:text-gray-400 hover:border-gray-300 hover:text-gray-600"
underline_classes =
if is_active && underline,
do: "",
else: "hover:border-gray-300"
build_class([base_classes, active_classes, underline_classes])
end
# Underline
defp get_tab_number_class(is_active, true) do
base_classes = "whitespace-nowrap ml-2 py-0.5 px-2 rounded-full text-xs font-normal"
active_classes =
if is_active,
do: "bg-primary-100 text-primary-600",
else: "bg-gray-100 text-gray-500"
underline_classes =
if is_active,
do: "bg-primary-100 dark:bg-primary-600 text-primary-600 dark:text-white",
else: "bg-gray-100 dark:bg-gray-600 dark:text-white text-gray-500"
build_class([base_classes, active_classes, underline_classes])
end
# Pill
defp get_tab_number_class(is_active, false) do
base_classes = "whitespace-nowrap ml-2 py-0.5 px-2 rounded-full text-xs font-normal"
active_classes =
if is_active,
do: "bg-primary-600 text-white",
else: "bg-gray-500 dark:bg-gray-600 text-white"
build_class([base_classes, active_classes])
end
end