Current section

Files

Jump to
moon lib moon light form field.ex
Raw

lib/moon/light/form/field.ex

defmodule Elixir.Moon.Light.Form.Field do
@moduledoc false
use Moon.Light.Component
import Moon.Light
attr(:id, :string, doc: "Id attribute for HTML tag", default: nil)
attr(:testid, :string, doc: "Data-testid attribute for HTML tag", default: nil)
attr(:class, :any, doc: "Additional Tailwind classes", default: nil)
attr(:attrs, :map, default: %{}, doc: "Additional attributes")
attr(:field, Phoenix.HTML.FormField, default: nil)
attr(:for, :string, doc: "Atom or changeset to inform the form data", default: nil)
attr(:size, :string, values: ~w(sm md lg xl), default: "md", doc: "Common moon size property")
attr(:title, :string, doc: "Label for input field", default: nil)
attr(:disabled, :boolean, default: false, doc: "Whether label has disabled state")
attr(:is_horizontal, :boolean, doc: "Whether label is on side of input field", default: nil)
attr(:on_click, Event, doc: "On click event for the label", default: nil)
attr(:value, :string, doc: "Value of the input", default: nil)
slot(:inner_block, doc: "Default slot")
def label(assigns) do
~H"""
<label
for={@for || (@field && @field.id)}
id={@id}
data-testid={@testid}
phx-click={Event.from(@on_click).name}
phx-target={Event.from(@on_click).target}
phx-value-value={@value}
class={
merge([
[
"flex gap-2 cursor-pointer whitespace-nowrap pb-2 items-center leading-normal",
(@size == "sm" && "text-moon-14") || "text-moon-16",
"text-bulma opacity-60 cursor-not-allowed": @disabled,
"font-medium pb-0 align-center": @is_horizontal
],
@class
])
}
{@attrs}
>
<%= render_slot(@inner_block) || @title %>
</label>
"""
end
attr(:testid, :string, doc: "Data-testid attribute for HTML tag", default: nil)
attr(:id, :string, doc: "Id attribute for HTML tag", default: nil)
attr(:class, :any, doc: "Additional Tailwind classes", default: nil)
attr(:has_error_icon, :boolean, default: false, doc: "Whether error icon is shown")
attr(:is_horizontal, :boolean, default: false, doc: "Whether label is on side of input field")
attr(:title, :string, doc: "Hint text when default slot is not given", default: nil)
slot(:inner_block, doc: "Default slot")
def hint(assigns) do
~H"""
<div
data-testid={@testid}
id={@id}
class={
merge([
[
"flex gap-1 items-center mt-2 text-moon-12 [&_svg]:text-moon-16",
"col-end-3": @is_horizontal
],
@class
])
}
>
<%= if has_slot?(@inner_block) do %>
<%= render_slot(@inner_block) %>
<% else %>
<p><%= @title %></p>
<% end %>
</div>
"""
end
attr(:testid, :string, doc: "Data-testid attribute for HTML tag", default: nil)
attr(:id, :string, doc: "Id attribute for HTML tag", default: nil)
attr(:class, :any, doc: "Additional Tailwind classes", default: nil)
attr(:has_error_icon, :boolean, default: false, doc: "Whether error icon is shown")
attr(:is_horizontal, :boolean, default: false, doc: "Whether label is on side of input field")
attr(:field, Phoenix.HTML.FormField, required: true)
slot(:inner_block, doc: "Default slot")
def error(assigns) do
~H"""
<div
data-testid={@testid}
id={@id}
class={
merge([
[
"flex gap-1 items-center mt-2 text-moon-12 [&_svg]:text-moon-16 text-chichi",
"col-end-3": @is_horizontal
],
@class
])
}
role="alert"
>
<%= if has_slot?(@inner_block) do %>
<%= render_slot(@inner_block) %>
<% else %>
<.icon :if={@has_error_icon} name="generic_info" />
<% end %>
<span :for={error <- @field.errors}>
<%= translate_error().(error) %>
</span>
</div>
"""
end
defp translate_error() do
&Surface.Components.Form.ErrorTag.translate_error/1
# TODO: fix for partners and get rid of surface
# case get_config(Surface.Components.Form.ErrorTag, :default_translator) do
# {module, function} -> &apply(module, function, [&1])
# nil -> &Surface.Components.Form.ErrorTag.translate_error/1
# end
end
end