DestroyedSoul
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?
Trending in Questions
Other Trending Topics
Latest Phoenix Threads
Latest on Elixir Forum
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 3- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
steffend
Keys should always refer to the comprehension item and are generally only useful if you render multiple items. It should probably still work since you most likely have a single error, but what happens if you drop the
:key?Apart from that I don’t see anything stand out, so if that doesn’t solve it please try to provide a script or repo to reproduce and open up an issue in LiveView!
DestroyedSoul
Ah, this is leftover from my attempts to fix it. Doesn’t work with or without
:key…Edited the original post to remove it.
DestroyedSoul
While I was trying to reproduce this issue in the new repo, I found the problem.
My
Inputsmodule was defined like this::htmlis there to get access totranslate_error(). However, I import all my custom components (indirectly) inhtml_helpers(). Apparently, it made a conflict even though compiler did not complain (because I importComponentsmodule, that, in its turn, has a__using__macro that makes available other components).I changed into:
and now the problem seems to have gone.