defmodule PetalComponents.Input do
use Phoenix.Component
@moduledoc """
Renders pure inputs (no label or errors).
"""
attr :id, :any, default: nil
attr :name, :any
attr :label, :string
attr :value, :any
attr :type, :string,
default: "text",
values: ~w(checkbox color date datetime-local email file hidden month number password
range radio radio_group search select switch tel text textarea time url week)
attr :field, Phoenix.HTML.FormField,
doc: "a form field struct retrieved from the form, for example: @form[:email]"
attr :checked, :boolean, doc: "the checked flag for checkbox inputs"
attr :prompt, :string, default: nil, doc: "the prompt for select inputs"
attr :options, :list, doc: "the options to pass to Phoenix.HTML.Form.options_for_select/2"
attr :multiple, :boolean, default: false, doc: "the multiple flag for select inputs"
attr :class, :string, default: nil, doc: "the class to add to the input"
attr :rest, :global,
include:
~w(autocomplete disabled form max maxlength min minlength list
pattern placeholder readonly required size step value name multiple prompt selected default year month day hour minute second builder options layout cols rows wrap checked accept)
def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
assigns
|> assign(field: nil, id: assigns.id || field.id)
|> assign_new(:name, fn ->
if assigns.multiple, do: field.name <> "[]", else: field.name
end)
|> assign_new(:value, fn -> field.value end)
|> assign_new(:label, fn -> Phoenix.HTML.Form.humanize(field.field) end)
|> assign(class: [assigns.class, get_class_for_type(assigns.type)])
|> input()
end
def input(%{type: "select"} = assigns) do
~H"""
<select id={@id} name={@name} class="pc-text-input" multiple={@multiple} {@rest}>
<option :if={@prompt} value=""><%= @prompt %></option>
<%= Phoenix.HTML.Form.options_for_select(@options, @value) %>
</select>
"""
end
def input(%{type: "textarea"} = assigns) do
~H"""
<textarea id={@id} name={@name} class="pc-text-input" {@rest}><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
"""
end
def input(%{type: "switch", value: value} = assigns) do
assigns =
assign_new(assigns, :checked, fn -> Phoenix.HTML.Form.normalize_value("checkbox", value) end)
~H"""
<label class="pc-switch">
<input
type="checkbox"
id={@id}
name={@name}
value="true"
checked={@checked}
class={["sr-only peer", @class]}
{@rest}
/>
<span class="pc-switch__fake-input"></span>
<span class="pc-switch__fake-input-bg"></span>
</label>
"""
end
def input(assigns) do
~H"""
<input
type={@type}
name={@name}
id={@id}
value={Phoenix.HTML.Form.normalize_value(@type, @value)}
class={@class}
{@rest}
/>
"""
end
defp get_class_for_type("radio"), do: "pc-radio"
defp get_class_for_type("checkbox"), do: "pc-checkbox"
defp get_class_for_type("color"), do: "pc-color-input"
defp get_class_for_type("file"), do: "pc-file-input"
defp get_class_for_type("range"), do: "pc-range-input"
defp get_class_for_type(_), do: "pc-text-input"
end