Packages
noora
0.78.1
0.84.1
0.84.0
0.83.2
0.83.1
0.83.0
0.82.7
0.82.6
0.82.5
0.82.4
0.82.3
0.82.2
0.82.1
0.82.0
0.81.4
0.81.3
0.81.2
0.81.1
0.81.0
0.80.1
0.80.0
0.79.1
0.79.0
0.78.1
0.78.0
0.77.4
0.77.3
0.77.2
0.77.1
0.77.0
0.76.0
0.75.0
0.74.0
0.73.0
0.72.0
0.71.0
0.70.0
0.69.1
0.69.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.2
0.64.1
0.64.0
0.63.2
0.63.1
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.0
0.57.0
0.56.1
0.56.0
0.55.0
0.54.0
0.53.1
0.53.0
0.52.1
0.52.0
0.51.0
0.50.1
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.3
0.44.2
0.44.1
0.44.0
0.43.0
0.42.0
0.41.0
0.40.6
0.40.5
0.40.4
0.40.3
0.40.2
0.40.1
0.40.0
0.39.1
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.1
0.32.0
0.31.0
0.30.0
0.29.2
0.29.1
0.29.0
0.28.5
0.28.4
0.28.3
0.28.2
0.28.1
0.28.0
0.27.0
0.26.1
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
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.0
0.1.0
0.1.0-rc.2
0.1.0-rc.1
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
A component library for Phoenix LiveView applications
Current section
Files
Jump to
Current section
Files
lib/noora/select.ex
defmodule Noora.Select do
@moduledoc """
A select dropdown component for choosing from a list of options.
## Example
```elixir
<.select id="country" label="Select Country" name="country" value="us">
<:item value="us" label="United States" icon="flag" />
<:item value="ca" label="Canada" icon="flag" />
<:item value="uk" label="United Kingdom" icon="flag" />
</.select>
```
"""
use Phoenix.Component
import Noora.Dropdown
import Noora.Icon
alias Phoenix.HTML.FormField
attr(:id, :string, required: true, doc: "Unique identifier for the dropdown component")
attr(:label, :string, required: true, doc: "Main text displayed in the dropdown trigger")
attr(:field, FormField, doc: "A Phoenix form field")
attr(:name, :string, doc: "The name attribute for the select input")
attr(:value, :string, doc: "The currently selected value")
attr(:hint, :string, default: nil, doc: "Hint text for the dropdown")
attr(:disabled, :boolean, default: nil, doc: "Whether the dropdown is disabled")
attr(:on_value_change, :string,
default: nil,
doc: "Event handler for when an option is selected"
)
slot(:inner_block, doc: "Content to be rendered inside the dropdown menu")
slot :item do
attr(:icon, :string)
attr(:label, :string)
attr(:value, :string)
end
def select(%{field: %FormField{} = field} = assigns) do
assigns
|> assign(field: nil, id: Map.get(assigns, :id, field.id))
|> assign_new(:name, fn -> field.name end)
|> assign_new(:value, fn -> field.value end)
|> select()
end
def select(assigns) do
~H"""
<div
id={@id}
class="noora-dropdown"
phx-hook="NooraSelect"
data-name={@name}
data-on-value-change={@on_value_change}
>
<button data-part="trigger" disabled={@disabled} type="button">
<div data-part="label-wrapper">
<div :if={Enum.find(@item, &(&1.value == @value))[:icon]} data-part="icon">
<.icon name={Enum.find(@item, &(&1.value == @value))[:icon]} />
</div>
<span data-part="label">{Enum.find(@item, &(&1.value == @value))[:label] || @label}</span>
</div>
<div data-part="indicator">
<div data-part="indicator-down">
<.chevron_down />
</div>
<div data-part="indicator-up">
<.chevron_up />
</div>
</div>
</button>
<div data-part="positioner">
<div class="noora-dropdown-content" data-part="content">
<.dropdown_item
:for={item <- @item}
data-part="item"
value={item.value}
label={item.label}
class="noora-dropdown-item"
>
<:left_icon :if={Map.has_key?(item, :icon)}><.icon name={item.icon} /></:left_icon>
{item.label}
</.dropdown_item>
</div>
</div>
<span :if={@hint} data-part="hint">
<.info_circle />
<span>{@hint}</span>
</span>
</div>
"""
end
end