Hello,
In my project I need custom core components, i.e. input fields etc that are styled a bit differently. I know I can provide class for the core input component, but then it only affects the text field itself not its label.
What I tried to do is to create my own Inputs.default_input, that would behave the same way as core input, but with custom tailwind classes. I literally copied the code form the core components and adjust the looks. Everything works, except for one thing:
Let’s take email as an example. When I start typing the email, the error is displayed that it has to have @ sign. This works for both my and core components.
However, when I add the @ sign and email becomes valid, the error should disappear. Works for core component, but not for my component.
My component is added like this:
<Inputs.default_input
field={@form[:email]}
type="email"
label="Email"
placeholder="Enter email address"
/>
The implementation mirrors the core component:
... attributes ...
def default_input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
errors = if Phoenix.Component.used_input?(field), do: field.errors, else: []
assigns
|> assign(field: nil, id: assigns.id || field.id)
|> assign(:errors, Enum.map(errors, &translate_error(&1)))
|> assign_new(:name, fn -> if assigns.multiple, do: field.name <> "[]", else: field.name end)
|> assign_new(:value, fn -> field.value end)
|> default_input()
end
... non text default_inputs()...
def default_input(assigns) do
~H"""
<div class="fieldset mb-2">
<label>
<span :if={@label} class="text-base text-base-content font-normal">{@label}</span>
<input
type={@type}
name={@name}
id={@id}
value={Phoenix.HTML.Form.normalize_value(@type, @value)}
class={[
@class || "mt-1 w-full input text-base text-base-content",
@errors != [] && (@error_class || "input-error text-base")
]}
{@rest}
/>
</label>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
"""
end
The only difference is tailwind classes in the default_input().
If I keep the code literally as-is, it still doesn’t work.
def default_input(assigns) do
~H"""
<div class="fieldset mb-2">
<label>
<span :if={@label} class="label mb-1">{@label}</span>
<input
type={@type}
name={@name}
id={@id}
value={Phoenix.HTML.Form.normalize_value(@type, @value)}
class={[
@class || "w-full input",
@errors != [] && (@error_class || "input-error")
]}
{@rest}
/>
</label>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
"""
end
But it starts to work when I do this:
def default_input(assigns) do
~H"""
<.input {assigns} />
"""
end
Is there anything special about the core components that I am missing?






















