Packages
moon
2.78.2
2.90.5
retired
2.90.4
2.90.3
2.90.2
2.90.1
2.90.0
2.89.4
2.89.1
2.89.0
2.88.0
2.87.11
2.87.10
2.87.9
2.87.8
2.87.7
2.87.6
2.87.5
2.87.4
2.87.3
2.87.2
2.87.1
2.87.0
2.86.1
2.86.0
2.85.1
2.85.0
2.84.0
2.83.0
2.82.0
2.81.4
2.81.3
2.81.2
2.81.1
2.81.0
2.80.2
2.80.1
2.80.0
2.79.13
2.79.12
2.79.11
2.79.10
2.79.9
2.79.8
2.79.7
2.79.6
2.79.5
2.79.4
2.79.3
2.79.2
2.79.1
2.79.0
2.78.4
2.78.3
2.78.2
2.78.1
2.78.0
2.77.0
2.76.5
2.76.4
2.76.3
2.76.2
2.76.1
2.76.0
2.75.0
2.74.1
2.74.0
2.73.8
2.73.7
2.73.6
2.73.5
2.73.4
2.73.3
2.73.2
2.73.1
2.73.0
2.72.5
2.72.4
2.72.3
2.72.2
2.72.1
2.72.0
2.71.1
2.71.0
2.70.0
2.69.2
2.69.1
2.69.0
2.68.11
2.68.10
Components-based design system written in elixir
Current section
Files
Jump to
Current section
Files
lib/moon/parts/wizzard/step.ex
defmodule Moon.Parts.Wizard.Step do
@moduledoc false
use Moon.StatelessComponent, slot: "tabs"
defstruct title: "", text: ""
# open API
@doc "Id attribute for DOM element"
prop(id, :string)
@doc "if true, the tab is disabled"
prop(disabled, :boolean, default: false)
@doc "Additional Tailwind classes"
prop(class, :css_class)
@doc "Data-testid attribute for DOM element"
prop(testid, :string)
@doc "Additional Tailwind classes for unselected tab"
prop(unselected_class, :css_class, default: "text-beerus")
@doc "Additional Tailwind classes for selected tab"
prop(selected_class, :css_class, default: "text-roshi")
@doc "Additional Tailwind classes for step icon background"
prop(icon_bg_class, :css_class, default: "bg-goku")
@doc "Additional Tailwind classes for step line"
prop(line_class, :css_class)
@doc "Additional Tailwind classes for step title"
prop(title_class, :css_class)
@doc "Content inside the tab"
slot(default)
# inner API
@doc "Will be got from Tabs.List in most cases"
prop(tabindex, :integer, from_context: :tabindex)
@doc "Will be got from Tabs.List in most cases"
prop(is_selected, :boolean, from_context: :is_selected)
@doc "Will be got from Tabs in most cases"
prop(on_change, :event, from_context: :on_change)
@doc "Will be got from Tabs.List in most cases"
prop(selected, :integer, from_context: :selected)
@doc "Will be got from Tabs.List in most cases"
prop(is_last, :boolean, from_context: :is_last)
def render(assigns) do
~F"""
<button
{=@id}
data-testid={@testid}
class={merge(["relative", @class])}
role="tab"
type="button"
{=@tabindex}
aria-selected={"#{@is_selected}"}
disabled={@disabled || @tabindex > @selected}
:on-click={!(@disabled || @tabindex > @selected) && @on_change}
value={@tabindex}
>
<div
class={merge([
[
"absolute left-3 top-4 -ml-px mt-0.5 h-full w-0.5 bg-beerus",
"bg-roshi": @selected > @tabindex
],
@line_class
])}
aria-hidden="true"
:if={!@is_last}
/>
<span class="group relative flex items-start">
<span class={merge(["flex items-center rounded-full", @icon_bg_class])}>
{#if @selected == @tabindex}
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
class={@selected_class}
>
<circle cx="12" cy="12" r="11" fill="none" stroke="currentColor" stroke-width="2" />
<circle cx="12" cy="12" r="3.5" fill="currentColor" stroke="currentColor" />
</svg>
{#elseif @selected > @tabindex}
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
class={@selected_class}
>
<circle cx="12" cy="12" r="12" fill="currentColor" />
<path
d="M8 12.6667L10.5455 15L16 10"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
{#else}
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
class={@unselected_class}
>
<circle cx="12" cy="12" r="11" fill="none" stroke="currentColor" stroke-width="2" />
</svg>
{/if}
</span>
<span class={merge([
"ml-0 md:ml-6 mb-6 gap-2 items-start flex min-h-[5rem] min-w-0 flex-col text-start",
@title_class
])}><#slot /></span>
</span>
</button>
"""
end
end