Packages
moon
2.87.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/dropdown.ex
defmodule Moon.Design.Dropdown do
@moduledoc "Component for rendering dropdown info, mostly lists"
# TODO: Add bottom sheet and backdrop animations
use Moon.StatefulComponent
@doc "Value(s) of the options to be marked as selected"
prop(value, :any)
@doc "Event fired when trigger is clicked"
prop(on_trigger, :event)
@doc "Event fired to close Dropdown.BottomOptions"
prop(on_close, :event)
@doc "Put true here if you want dropdown to be shown by default"
prop(is_open, :boolean)
@doc "Addictional classes to be added to a dropdown"
prop(class, :css_class)
@doc "Data-testid attribute for HTML tag"
prop(testid, :string)
@doc "Dropdown autoclose on click away"
prop(autoclose, :boolean, default: true)
@doc "Disabled state for the dropdown"
prop(disabled, :boolean)
@doc "Attribute phx-hook. Used for dependant components"
prop(hook, :string)
@doc """
Experimental: makes BottomSheet behave as Modal on some screen widths,
please reffer to https://tailwindcss.com/docs/screens
"""
prop(as_dropdown_on, :string, values: ~w(sm md lg xl 2xl))
@doc "Additional values to be passed"
prop(side_values, :map, default: %{})
@doc "Event fired when option is selected"
prop(on_change, :event)
@doc "Slot for triggering the open/closing state"
slot(trigger, required: true)
@doc "Content to be showable"
slot(default)
@doc "Backdrop of Dropdown as BottomSheet on small screens, see Dropdown.Backdrop"
slot(backdrop)
def handle_event("on_change_default", %{"value" => value}, socket) do
{:noreply, assign(socket, value: value, is_open: false)}
end
def handle_event("on_trigger_default", _, socket) do
{:noreply, assign(socket, is_open: !socket.assigns.is_open)}
end
def handle_event("close_me", _, socket) do
{:noreply, assign(socket, is_open: false)}
end
def handle_event("open_me", _, socket) do
{:noreply, assign(socket, is_open: true)}
end
def close(dropdown_id) do
send_update_after(__MODULE__, [id: dropdown_id, is_open: false], 100)
end
def render(assigns) do
~F"""
<div
class={merge(["relative", get_config(:default_class), @class])}
:on-click-away={(@autoclose && "close_me") || nil}
{=@id}
data-testid={@testid}
phx-hook={@hook}
>
<#slot
{
@trigger,
value: @value,
is_open: @is_open,
disabled: @disabled,
on_trigger: @on_trigger || %{name: "on_trigger_default", target: @myself}
}
context_put={
is_open: @is_open,
disabled: @disabled,
on_trigger: @on_trigger || %{name: "on_trigger_default", target: @myself},
open_me: %{name: "open_me", target: @myself},
close_me: %{name: "close_me", target: @myself}
}
/>
<#slot
{@backdrop}
context_put={
is_open: @is_open,
as_dropdown_on: @as_dropdown_on
}
/>
<#slot context_put={
values: @side_values,
on_change: @on_change || %{name: "on_change_default", target: @myself},
close_me: @on_close || %{name: "close_me", target: @myself},
is_open: @is_open,
value: @value,
as_dropdown_on: @as_dropdown_on
} />
</div>
"""
end
end