Formularios

Estado: Estable

Campo de texto

El campo de texto de todos los formularios, envuelto en Field (etiqueta, ayuda, error y aria resueltos). Lleva unidades o íconos dentro ("$", "MXN", "min"), una X para limpiar búsquedas, un ojo que parpadea con resorte para ver la contraseña y, en el registro, un medidor de seguridad que se llena segmento a segmento. Con un form builder toma nombre, valor y error del modelo.

app/views/… (la demo de arriba)

<%# En la tarjeta del índice se ven el registro (correo y contraseña con su
    medidor) y la búsqueda; en el escenario grande, también precio y duración. %>
<div class="@container w-full max-w-3xl">
  <div class="grid gap-x-10 gap-y-5 @xl:grid-cols-2">
    <div class="grid content-start gap-4">
      <p class="eui-label hidden @xl:block">Crear cuenta</p>
      <%= render Ui::InputComponent.new(name: "input_demo[email]", id: "input-demo-email", type: "email", label: "Correo electrónico",
                                        placeholder: "tu@correo.com", autocomplete: "email", required: true) do |input| %>
        <% input.with_leading do %>
          <%= render Ui::IconComponent.new(:mail) %>
        <% end %>
      <% end %>
      <%= render Ui::InputComponent.new(name: "input_demo[password]", id: "input-demo-password", type: "password", label: "Contraseña",
                                        placeholder: "Al menos 8 caracteres", autocomplete: "new-password", required: true, strength: true) %>
    </div>

    <div class="grid content-start gap-4">
      <p class="eui-label hidden @xl:block">Admin</p>
      <%= render Ui::InputComponent.new(name: "q", id: "input-demo-search", type: "search", label: "Buscar cliente", hide_label: true,
                                        placeholder: "Buscar cliente por nombre o correo", value: "Mariana", clearable: true) do |input| %>
        <% input.with_leading do %>
          <%= render Ui::IconComponent.new(:search) %>
        <% end %>
      <% end %>
      <div class="hidden grid-cols-2 gap-4 @xl:grid">
        <%= render Ui::InputComponent.new(name: "input_demo[price]", id: "input-demo-price", type: "number", label: "Precio",
                                          value: 1350, min: 0, step: 50, leading: "$", trailing: "MXN", hint: "Paquete de 10 clases") %>
        <%= render Ui::InputComponent.new(name: "input_demo[duration]", id: "input-demo-duration", type: "number", label: "Duración",
                                          value: 40, min: 15, step: 5, trailing: "min", error: "Reformer: mínimo 45 min") %>
      </div>
    </div>
  </div>
</div>

Qué hace

  • Ui::InputComponent.classes(invalid:, size:) da la misma superficie para un f.text_field propio.
  • El ojo es un solo trazo que parpadea con el resorte "responsive"; la contraseña se oculta otra vez al enviar y antes de que Turbo guarde la página en caché.
  • El medidor cuenta 8+ caracteres, número y mayúscula (más símbolo o 12+ para el cuarto segmento) y lista lo que falta.
  • La X avisa con input y change, así los buscadores en vivo reaccionan; Esc también borra.
  • Sin JS es un input nativo: los botones y el medidor solo aparecen cuando el controlador se conecta.

Props

Nombre Tipo Default Descripción
name String nil Nombre del campo. Con form: + attribute: sale del builder.
type String "text" email, password, tel, url, search, number, date, time, datetime (= datetime-local)…
label String nil Etiqueta visible. Sin ella el campo queda nombrado por placeholder (etiqueta oculta).
value / placeholder String nil Valor inicial y texto de ejemplo. Fechas y horas se formatean solas.
form: + attribute: FormBuilder, Symbol nil Nombre, id, valor y error salen del modelo (usa f.email_field, f.number_field…).
hint / error String nil Ayuda y error (el error del modelo se toma solo con form:).
required / optional / disabled Boolean false Asterisco, marca de Opcional o deshabilitado.
size :sm | :md | :lg :md Alto del control (sigue el dial de densidad).
leading: / trailing: String nil Texto corto dentro del campo: "$", "MXN", "min", "@". Se lee como descripción.
with_leading / with_trailing slot — Un ícono de 16px dentro del campo (decorativo).
clearable Boolean | String false Botón X para borrar; con String, su nombre accesible ("Borrar búsqueda" por defecto en search).
strength Boolean false Solo password: medidor de seguridad para contraseñas nuevas.
reveal Boolean true Solo password: botón para mostrar/ocultar.
**attrs Hash {} id, autocomplete, min, step, data, aria… van al <input>; class: se suma a la superficie.

Accesibilidad