Current section

Files

Jump to
moon lib moon_web pages components select dropdown_page.ex
Raw

lib/moon_web/pages/components/select/dropdown_page.ex

defmodule MoonWeb.Pages.Components.Select.DropdownPage do
@moduledoc false
use MoonWeb, :live_view
alias Moon.Components.Button
alias Moon.Components.Checkbox
alias Moon.Components.Form
alias Moon.Components.Field
alias Moon.Components.FieldLabel
alias Moon.Components.Select.Dropdown
alias Moon.Components.Select.Dropdown.Footer
alias Moon.Components.ListItems.SingleLineItem
alias Moon.Components.Tabs
alias Moon.Components.Tabs.TabLink
alias MoonWeb.Components.ExampleAndCode
alias MoonWeb.Components.Page
alias MoonWeb.Pages.Tutorials.AddDataUsingForm.User
alias MoonWeb.Components.ComponentPageDescription
data(breadcrumbs, :any,
default: [
%{
to: "#",
name: "Components"
},
%{
to: "/components/select/dropdown",
name: "Multi Select"
}
]
)
data(search_string, :string, default: "")
def mount(_params, _session, socket) do
user_changeset = User.changeset(%User{}, %{permissions: [1, 2], role: 1})
{:ok,
assign(socket,
user_changeset: user_changeset,
radio_form_changeset: user_changeset,
options: User.available_permissions(),
searched_options: User.available_permissions(),
options_with_left_icon: User.available_permissions_with_left_icon(),
searched_options_with_left_icon: User.available_permissions_with_left_icon(),
search_string: "",
tab_id: "1",
selected: [],
latest_params: nil
)}
end
def handle_params(_params, uri, socket) do
{:noreply, assign(socket, uri: uri)}
end
def render(assigns) do
~F"""
<Page {=@theme_name} {=@active_page} {=@breadcrumbs} {=@direction}>
<ComponentPageDescription title="Dropdown">
<p>Dropdowns is a custom select component that allows users to make single or multiple selections.</p>
<p>An option that's been selected can represent a corresponding value in forms or be used to filter/sort content.containers as Popovers, Sidebars, Drawers, Dialogs etc.</p>
</ComponentPageDescription>
<ExampleAndCode title="Options" id="dropdown-options-example">
<:example>
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown id="dropdown-options-example-user-permissions" options={@options} is_multi />
</Field>
</Form>
</:example>
<:code>{code_for_dropdown()}</:code>
<:state>@user_changeset = {inspect(@user_changeset, pretty: true)}</:state>
</ExampleAndCode>
<ExampleAndCode title="With icons" id="dropdown-icons-example">
<:example>
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown id="dropdown-icons-example-user-permissions" is_multi options={@options}>
{#for option <- @options}
<Dropdown.Option value={"#{option.value}"} :let={is_selected: is_selected}>
<SingleLineItem current={is_selected}>
<:left_icon><Moon.Icons.ControlsPlus /></:left_icon>
{option.label}
<:right_icon><Moon.Icons.ControlsPlus /></:right_icon>
</SingleLineItem>
</Dropdown.Option>
{/for}
</Dropdown>
</Field>
</Form>
</:example>
<:code>{code_for_dropdown()}</:code>
<:state>@user_changeset = {inspect(@user_changeset, pretty: true)}</:state>
</ExampleAndCode>
<ExampleAndCode title="With search and footer (markup)" id="search_and_footer_markup">
<:example>
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown
id="random-id-38943"
available_options={@options}
options={@searched_options}
on_search_change="update_search"
search_string={@search_string}
is_multi
>
{#for option <- @searched_options}
<Dropdown.Option value={"#{option.value}"} :let={is_selected: is_selected}>
<SingleLineItem current={is_selected}>
<:left_icon><Moon.Icons.ControlsPlus /></:left_icon>
{option.label}
<:right_icon>
<Checkbox
id={"random-id-38943_#{option.value}"}
field={:user_permissions_options_checked}
checked={is_selected}
/>
</:right_icon>
</SingleLineItem>
</Dropdown.Option>
{/for}
<:footer>
<Footer>
<:cancel>
<Button variant="secondary" size="sm">Cancel</Button>
</:cancel>
<:clear>
<Button variant="ghost" size="sm" on_click="clear_selections">Clear</Button>
</:clear>
<:confirm>
<Button variant="primary" size="sm">Confirm</Button>
</:confirm>
</Footer>
</:footer>
</Dropdown>
</Field>
</Form>
</:example>
<:code>{code_for_dropdown_search_footer()}</:code>
<:state>@user_changeset = {inspect(@user_changeset, pretty: true)}</:state>
</ExampleAndCode>
<ExampleAndCode
title="With search and footer (data + atom form)"
id="with_search_and_footer_data_and_form_for_atom"
>
<:example>
<Form
id="with_search_and_footer_data_and_form_for_atom_form"
for={:selected_params}
change="update_selected"
submit="apply"
>
<Field name={:selected}>
<Dropdown
id="with_search_and_footer_data_and_form_for_atom_form_dropdown"
available_options={@options_with_left_icon}
options={@searched_options_with_left_icon}
value={@selected}
on_search_change="update_search"
search_string={@search_string}
with="checkbox"
is_multi
>
<:footer>
<Footer>
<:cancel>
<Button variant="secondary" size="sm">Cancel</Button>
</:cancel>
<:clear>
<Button variant="ghost" size="sm" on_click="clear_selections">Clear</Button>
</:clear>
<:confirm>
<Button variant="primary" size="sm">Confirm</Button>
</:confirm>
</Footer>
</:footer>
</Dropdown>
</Field>
</Form>
</:example>
<:code>{code_for_with_search_and_footer_data_and_form_for_atom_form_dropdown()}</:code>
<:state>@user_changeset = {inspect(@user_changeset, pretty: true)}</:state>
</ExampleAndCode>
<ExampleAndCode
title="With search and footer (data + changeset form)"
id="with_search_and_footer_data_changeset"
>
<:example>
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown
id="search_and_footer_data_for_changeset_dropdown"
available_options={@options_with_left_icon}
options={@searched_options_with_left_icon}
on_search_change="update_search"
search_string={@search_string}
with="checkbox"
is_multi
>
<:footer>
<Footer>
<:cancel>
<Button variant="secondary" size="sm">Cancel</Button>
</:cancel>
<:clear>
<Button variant="ghost" size="sm" on_click="clear_selections">Clear</Button>
</:clear>
<:confirm>
<Button variant="primary" size="sm">Confirm</Button>
</:confirm>
</Footer>
</:footer>
</Dropdown>
</Field>
</Form>
</:example>
<:code>{code_for_dropdown_search_footer_and_data_and_form_changeset()}</:code>
<:state>@user_changeset = {inspect(@user_changeset, pretty: true)}</:state>
</ExampleAndCode>
<ExampleAndCode title="With radio button" id="dropdown-radio-example">
<:example>
<Form for={@radio_form_changeset} change="form_radio_update" submit="form_submit">
<Dropdown
id="user-role"
field={:role}
options={User.available_roles_with_left_icon()}
with="radio"
/>
</Form>
</:example>
<:code>{code_for_dropdown_radio_button()}</:code>
<:state>{state_for_dropdown_radio_button(assigns)}</:state>
</ExampleAndCode>
<ExampleAndCode title="With checkbox" id="dropdown-checkbox-example">
<:example>
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown
id="dropdown-checkbox-example-user-permissions"
available_options={@options}
options={@searched_options}
is_multi
>
{#for option <- @searched_options}
<Dropdown.Option value={"#{option.value}"} :let={is_selected: is_selected}>
<SingleLineItem current={is_selected}>
<:left_icon><Moon.Icons.ControlsPlus /></:left_icon>
{option.label}
<:right_icon>
<Checkbox
id={"user_permissions_#{option.value}"}
field={:user_permissions_options_checked}
checked={is_selected}
/>
</:right_icon>
</SingleLineItem>
</Dropdown.Option>
{/for}
</Dropdown>
</Field>
</Form>
</:example>
<:code>{code_for_dropdown_checkbox()}</:code>
<:state>@user_changeset = {inspect(@user_changeset, pretty: true)}</:state>
</ExampleAndCode>
<ExampleAndCode title="With Tabs" id="dropdown-tabs-example">
<:example>
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown id="dropdown-tabs-example-user-permissions" options={@options} is_multi>
<:header>
<Tabs>
<TabLink active={@tab_id == "1"} on_click="clicked_tab" item_id="1">Link 1</TabLink>
<TabLink active={@tab_id == "2"} on_click="clicked_tab" item_id="2">Link 2</TabLink>
<TabLink active={@tab_id == "3"} on_click="clicked_tab" item_id="3">Link 3</TabLink>
<TabLink active={@tab_id == "4"} on_click="clicked_tab" item_id="4">Link 4</TabLink>
</Tabs>
</:header>
</Dropdown>
</Field>
</Form>
</:example>
<:code>{code_for_dropdown_tabs()}</:code>
<:state>@user_changeset = {inspect(@user_changeset, pretty: true)}</:state>
</ExampleAndCode>
</Page>
"""
end
def handle_event("update_selected", params, socket) do
%{"selected_params" => selected_params} = params
selected = selected_params["selected"] || []
{:noreply, assign(socket, selected: selected)}
end
def handle_event(
"form_update",
params,
socket
) do
user_params = params["user"] || %{permissions: []}
user_changeset = User.changeset(%User{}, user_params)
{:noreply, assign(socket, user_changeset: user_changeset, latest_params: user_params)}
end
def handle_event(
"form_submit",
%{
"user" => user_params
},
socket
) do
user_changeset = User.changeset(%User{}, user_params)
{:noreply, assign(socket, user_changeset: user_changeset)}
end
def handle_event("form_radio_update", params, socket) do
user_params = params["user"] || %{"role" => nil}
user_changeset = User.changeset(%User{}, user_params)
{:noreply, assign(socket, radio_form_changeset: user_changeset, latest_params: user_params)}
end
def handle_event("clear_selections", _params, socket) do
user_changeset = User.changeset(%User{}, %{"permissions" => []})
{:noreply, assign(socket, user_changeset: user_changeset)}
end
def handle_event(
"update_search",
%{"value" => search_string},
socket
) do
options = socket.assigns.options
options_with_left_icon = socket.assigns.options_with_left_icon
searched_options =
options
|> Enum.filter(&String.contains?(String.downcase(&1.label), String.downcase(search_string)))
searched_options_with_left_icon =
options_with_left_icon
|> Enum.filter(&String.contains?(String.downcase(&1.label), String.downcase(search_string)))
{:noreply,
assign(socket,
searched_options: searched_options,
searched_options_with_left_icon: searched_options_with_left_icon,
search_string: search_string
)}
end
def handle_event("clicked_tab", %{"item_id" => tab_id}, socket) do
{:noreply, assign(socket, tab_id: tab_id)}
end
def code_for_dropdown do
"""
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown id="dropdown-options-example-user-permissions" options={User.available_permissions()} is_multi />
</Field>
</Form>
"""
end
def code_for_dropdown_search_footer do
"""
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown
id="random-id-38943"
available_options={@options}
options={@searched_options}
on_search_change="update_search"
search_string={@search_string}
is_multi
>
{#for option <- @searched_options}
<Dropdown.Option value={"\#{option.value}"} :let={is_selected: is_selected}>
<SingleLineItem current={is_selected}>
<:left_icon><Moon.Icons.ControlsPlus /></:left_icon>
{option.label}
<:right_icon>
<Checkbox
id={"random-id-38943_\#{option.value}"}
field={:user_permissions_options_checked}
checked={is_selected}
/>
</:right_icon>
</SingleLineItem>
</Dropdown.Option>
{/for}
<:footer>
<Footer>
<:cancel>
<Button variant="secondary" size="sm">Cancel</Button>
</:cancel>
<:clear>
<Button variant="ghost" size="sm" on_click="clear_selections">Clear</Button>
</:clear>
<:confirm>
<Button variant="primary" size="sm">Confirm</Button>
</:confirm>
</Footer>
</:footer>
</Dropdown>
</Field>
</Form>
"""
end
def code_for_with_search_and_footer_data_and_form_for_atom_form_dropdown do
"""
<Form
id="with_search_and_footer_data_and_form_for_atom_form"
for={:selected_params}
change="update_selected"
submit="apply"
>
<Field name={:selected}>
<Dropdown
id="with_search_and_footer_data_and_form_for_atom_form_dropdown"
available_options={@options_with_left_icon}
options={@searched_options_with_left_icon}
value={@selected}
on_search_change="update_search"
search_string={@search_string}
with="checkbox"
is_multi
>
<:footer>
<Footer>
<:cancel>
<Button variant="secondary" size="sm">Cancel</Button>
</:cancel>
<:clear>
<Button variant="ghost" size="sm" on_click="clear_selections">Clear</Button>
</:clear>
<:confirm>
<Button variant="primary" size="sm">Confirm</Button>
</:confirm>
</Footer>
</:footer>
</Dropdown>
</Field>
</Form>
"""
end
def code_for_dropdown_search_footer_and_data_and_form_changeset do
"""
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permissions}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown
id="search_and_footer_data_dropdown"
available_options={@options_with_left_icon}
options={@searched_options_with_left_icon}
on_search_change="update_search"
search_string={@search_string}
with="checkbox"
is_multi
>
<:footer>
<Footer>
<:cancel>
<Button variant="secondary" size="sm">Cancel</Button>
</:cancel>
<:clear>
<Button variant="ghost" size="sm" on_click="clear_selections">Clear</Button>
</:clear>
<:confirm>
<Button variant="primary" size="sm">Confirm</Button>
</:confirm>
</Footer>
</:footer>
</Dropdown>
</Field>
</Form>
"""
end
def code_for_dropdown_radio_button do
"""
<Form for={@radio_form_changeset} change="form_radio_update" submit="form_submit">
<Dropdown id="user-role" field={:role} options={User.available_roles_with_left_icon()} with="radio" />
</Form>
"""
end
def state_for_dropdown_radio_button(assigns) do
"""
@radio_form_changeset = #{inspect(assigns.radio_form_changeset, pretty: true)}
@latest_params = #{inspect(assigns.latest_params, pretty: true)}
"""
end
def code_for_dropdown_checkbox do
"""
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permission}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown
id="dropdown-checkbox-example-user-permissions"
options={@searchable_options}
is_multi>
{#for option <- @searchable_options}
<Dropdown.Option value="option.value" :let={is_selected: is_selected}>
<SingleLineItem current={is_selected}>
<:left_icon><Moon.Icons.ControlsPlus /></:left_icon>
{option.label}
<:right_icon>
<Checkbox checked={is_selected}/>
</:right_icon>
</SingleLineItem>
</Dropdown.Option>
{/for}
</Dropdown>
</Field>
</Form>
"""
end
def code_for_dropdown_tabs do
"""
<Form for={@user_changeset} change="form_update" submit="form_submit">
<Field name={:permission}>
<FieldLabel>Permissions</FieldLabel>
<Dropdown
id="dropdown-tabs-example-user-permissions"
options={@options}>
<:header>
<Tabs>
<TabLink active={@tab_id == "1"} on_click="clicked_tab" item_id="1">Link 1</TabLink>
<TabLink active={@tab_id == "2"} on_click="clicked_tab" item_id="2">Link 2</TabLink>
<TabLink active={@tab_id == "3"} on_click="clicked_tab" item_id="3">Link 3</TabLink>
<TabLink active={@tab_id == "4"} on_click="clicked_tab" item_id="4">Link 4</TabLink>
</Tabs>
</:header>
</Dropdown>
</Field>
</Form>
"""
end
end