Packages
moon
2.76.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/design/accordion.ex
defmodule Moon.Design.Accordion do
@moduledoc false
use Moon.StatefulComponent
import Moon.Helpers.MakeList
@doc "Data-testid attribute for DOM element"
prop(testid, :string)
@doc "Additional Tailwind classes"
prop(class, :css_class)
@doc "Size of the item, header mostly"
prop(item_size, :string, values!: ["sm", "md", "lg", "xl"], default: "md")
@doc "Content looks outside"
prop(has_content_outside, :boolean, default: false)
@doc "Value (List of values) items to be open"
prop(value, :any, default: [])
@doc "Handler for open/close of the item"
prop(on_change, :event)
@doc "Close other items if true"
prop(is_single_open, :boolean, default: false)
@doc "Accordion item, see Accordion.Item"
slot(item, required: true)
def handle_event("on_change_default", _params = %{"value" => index}, socket) do
list = make_list(socket.assigns[:value])
{:noreply,
assign(socket,
value:
(Enum.member?(list, index) &&
Enum.filter(list, &(&1 != index))) ||
((socket.assigns.is_single_open && [index]) || [index | list])
)}
end
def render(assigns) do
~F"""
<div class={merge(["flex w-full gap-2 flex-col", @class])} {=@id} data-testid={@testid}>
{#for {item, index} <- Enum.with_index(make_list(@item))}
<#slot
{item}
context_put={
is_open: Enum.member?(make_list(@value), item.value || to_string(index)),
size: @item_size,
value: to_string(index),
on_change: @on_change || %{name: "on_change_default", target: @myself},
has_content_outside: @has_content_outside
}
/>
{/for}
</div>
"""
end
end