Packages
moon
2.81.0
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/text_input.ex
defmodule Moon.Components.TextInput do
@moduledoc false
use Moon.StatelessComponent
alias Moon.Components.InputGroup
alias Moon.Components.TextInput.TextInputBasic
alias Moon.Components.TextInput.TextInputInnerLabel
alias Moon.Components.TextInput.TextInputPassword
alias Moon.Components.TextInput.HintText
alias Surface.Components.Context
prop(id, :string)
prop(field, :atom, from_context: {Surface.Components.Form.Field, :field})
prop(size, :string, values: ["md", "lg", "xl"], default: "md")
prop(type, :string,
values: [
"date",
"month",
"datetime-local",
"email",
"number",
"password",
"search",
"tel",
"text",
"time",
"url"
],
default: "text"
)
prop(placeholder, :string, default: " ")
prop(is_error, :boolean)
prop(background_color, :string, values: Moon.colors(), default: "bg-goku")
prop(is_first, :boolean)
prop(disabled, :boolean)
prop(label, :string)
prop(required, :boolean)
prop(step, :string, default: "1")
prop(class, :css_class)
prop(min, :string)
prop(max, :string)
prop(readonly, :boolean)
prop(value, :string)
prop(focus, :event)
prop(keydown, :event)
prop(keyup, :event)
prop(blur, :event)
prop(show_password_text, :string, default: "Show")
prop(use_error_tag, :boolean)
slot(left_icon_slot)
slot(right_icon_slot)
slot(hint_text_slot)
data(form, :form, from_context: {Surface.Components.Form, :form})
data(is_in_input_group, :boolean, from_context: {InputGroup, :is_in_input_group})
data(group_class_plain, :css_class, from_context: {InputGroup, :group_class_plain})
def render(assigns) do
assigns = put_everything_to_context(assigns)
internal_render = ~F"""
<HintText :if={slot_assigned?(:hint_text_slot)} {=@is_error}>
<#slot {@hint_text_slot} />
</HintText>
"""
~F"""
{#if @type == "password"}
<TextInputPassword
{=@id}
{=@field}
class={@class, "#{get_combined_class(@is_in_input_group, @field, @group_class_plain)}": true}
>
<:left_icon_slot>
<#slot {@left_icon_slot} />
</:left_icon_slot>
<:right_icon_slot>
<#slot {@right_icon_slot} />
</:right_icon_slot>
{internal_render}
</TextInputPassword>
{#elseif @size == "xl"}
<TextInputInnerLabel
{=@id}
{=@field}
class={@class, "#{get_combined_class(@is_in_input_group, @field, @group_class_plain)}": true}
>
<:left_icon_slot>
<#slot {@left_icon_slot} />
</:left_icon_slot>
<:right_icon_slot>
<#slot {@right_icon_slot} />
</:right_icon_slot>
{internal_render}
</TextInputInnerLabel>
{#else}
<TextInputBasic {=@id} {=@field} {=@class}>
<:left_icon_slot>
<#slot {@left_icon_slot} />
</:left_icon_slot>
<:right_icon_slot>
<#slot {@right_icon_slot} />
</:right_icon_slot>
{internal_render}
</TextInputBasic>
{/if}
"""
end
defp put_everything_to_context(assigns) do
assigns
|> Context.put(
__MODULE__,
assigns
|> Map.delete(:left_icon_slot)
|> Map.delete(:right_icon_slot)
|> Map.delete(:hint_text_slot)
)
|> Context.put(__MODULE__,
is_error: has_error(assigns[:is_error], assigns[:form], assigns[:field]),
has_left_icon: slot_assigned?(:left_icon_slot),
has_right_icon: slot_assigned?(:right_icon_slot)
)
end
defp get_combined_class(is_in_input_group, field, group_class_plain) do
if is_in_input_group && !field do
group_class_plain
end
end
defp has_error(is_error, form, field) do
is_error || (field && form && Keyword.has_key?(form.errors, field))
end
end