Packages
moon
2.76.1
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/components/select/multi_select.ex
defmodule Moon.Components.Select.MultiSelect.Labels.SelectedLabel do
@moduledoc false
use Moon.StatelessComponent
alias Moon.Components.Label
alias Moon.Components.Select.Helpers, as: SelectHelpers
alias Moon.Icons.ControlsClose
alias Phoenix.LiveView.JS
prop(select_id, :string)
prop(option, :any)
prop(size, :string)
prop(disabled, :boolean)
prop(selected_label_background_color_class, :css_class)
prop(selected_label_text_color_class, :css_class)
def render(assigns) do
~F"""
{#if @option}
<Label
class={SelectHelpers.innerlabel_font_class(@size)}
background_color={@selected_label_background_color_class}
color={@selected_label_text_color_class}
>
{@option.label}
<:right_icon>
<div
class="cursor-pointer"
:on-click={!@disabled &&
JS.dispatch("moon:update-select",
detail: %{value: @option.value, selected: false},
to: "##{@select_id}"
)}
><ControlsClose /></div>
</:right_icon>
</Label>
{/if}
"""
end
end
defmodule Moon.Components.Select.MultiSelect.Labels do
@moduledoc false
use Moon.StatelessComponent
alias Moon.Components.Select.Helpers, as: SelectHelpers
alias __MODULE__.SelectedLabel
prop(select_id, :string)
prop(options, :list, default: [])
prop(value, :list, default: [])
prop(size, :string)
prop(prompt, :string)
prop(disabled, :boolean)
prop(selected_label_background_color_class, :css_class)
prop(selected_label_text_color_class, :css_class)
def render(assigns) do
~F"""
{#if @value && @value != []}
<div
class={"gap-1", "grid grid-cols-1": @prompt}
style={get_style("grid-auto-flow": if(@prompt, do: "row"))}
>
{#if @prompt}
<div class="text-trunks text-moon-14" style="grid-col: span 2 / span 2;">
{@prompt}
</div>
{/if}
<div
class="flex justify-start gap-1"
style={get_style("grid-col": if(@prompt, do: "span 2 / span 2"))}
>
{#for v <- @value}
<SelectedLabel
{=@select_id}
{=@size}
{=@disabled}
{=@selected_label_background_color_class}
{=@selected_label_text_color_class}
option={SelectHelpers.get_option(@options, v)}
/>
{/for}
</div>
</div>
{#else}
<div class={
"text-trunks",
SelectHelpers.prompt_font_class(@size)
}>
{@prompt}
</div>
{/if}
"""
end
end
# https://www.figma.com/file/S3q1SkVngbwHuwpxHKCsgtJj/Moon---Components?node-id=22819%3A17501
defmodule Moon.Components.Select.MultiSelect do
@moduledoc false
use Moon.StatefulComponent
alias Moon.Autolayouts.PullAside
alias Moon.Autolayouts.TopToDown
alias Moon.Components.FieldBorder
alias Moon.Components.Popover
alias Moon.Components.Select.Dropdown
alias Moon.Components.Select.Helpers, as: SelectHelpers
alias __MODULE__.Labels
prop(field, :atom, from_context: {Surface.Components.Form.Field, :field})
prop(form, :form, from_context: {Surface.Components.Form, :form})
prop(label, :string)
prop(options, :any, default: [])
prop(value, :any)
prop(prompt, :string)
prop(error, :string)
prop(disabled, :boolean, default: false)
prop(required, :boolean)
prop(class, :string)
prop(size, :string, values: ~w(small medium large xlarge), default: "medium")
prop(popover_placement, :string, default: "bottom-start")
prop(popover_class, :string)
prop(field_border_class, :string, default: FieldBorder.get_default_states_class())
prop(field_border_color_class, :string, values: Moon.colors(), default: "goku")
prop(selected_label_background_color_class, :css_class, default: "bulma")
prop(selected_label_text_color_class, :css_class, default: "goku")
prop(searched_options, :any, default: nil)
prop(on_search_change, :event)
prop(search_string, :string, default: nil)
prop(with, :string, default: nil)
prop(search_min_width, :css_class, default: "min-w-[144px]")
data(open, :boolean, default: false)
slot(default)
def render(assigns) do
~F"""
<Popover placement={@popover_placement} show={@open} on_close="close" class={@popover_class}>
{Phoenix.HTML.Form.multiple_select(@form, @field, SelectHelpers.get_formatted_options(@options),
class: "hidden",
id: @id
)}
<FieldBorder
testid={"#{@id}-toggle_open"}
click="toggle_open"
states_class={@field_border_class}
class={
"w-full",
"bg-#{@field_border_color_class}": @field_border_color_class
}
>
<PullAside class={
"leading-6",
SelectHelpers.get_padding(@size),
get_disabled_class(@disabled)
}>
<:left>
<Labels
select_id={@id}
value={SelectHelpers.get_normalized_value(@form, @field, true, value: @value)}
{=@options}
{=@prompt}
{=@size}
{=@disabled}
{=@selected_label_background_color_class}
{=@selected_label_text_color_class}
/>
</:left>
<:right>
<Moon.Icons.ControlsChevronDown />
</:right>
</PullAside>
</FieldBorder>
<:content>
<TopToDown>
<div class={
"overflow-auto rounded-moon-i-md box-border border border-solid",
"border-beerus min-h-[20px] max-h-[200px] drop-shadow-2xl",
"#{@search_min_width}": not is_nil(@on_search_change)
}>
<Dropdown
class="w-auto"
id={"#{@id}-dropdown"}
select_id={@id}
available_options={@options}
options={@searched_options || @options}
{=@disabled}
{=@on_search_change}
{=@search_string}
{=@with}
is_multi
/>
</div>
</TopToDown>
</:content>
</Popover>
"""
end
def handle_event("close", _params, socket) do
socket = assign(socket, open: false)
{:noreply, socket}
end
def handle_event("toggle_open", _params, socket) do
if socket.assigns.disabled == false do
{:noreply, assign(socket, open: !socket.assigns.open)}
else
{:noreply, socket}
end
end
defp get_disabled_class(disabled) do
if disabled do
"opacity-60 cursor-not-allowed"
end
end
end