Formularios
Estado: BetaÁrea de texto
Para descripciones de clases, notas internas o comentarios. Empieza con pocos renglones y crece con resorte mientras escribes hasta un máximo; después hace scroll. Con un límite de caracteres muestra un contador mono con un anillo que se llena y cambia de tono al acercarse.
- Resorte
- Formularios
- Form builder
Hasta 280 caracteres.
Se muestra en el horario y en la ficha de la clase.
Hasta 140 caracteres.
Por ejemplo: lesión de rodilla, usa reformer 3.
Hasta 280 caracteres.
Se muestra en el horario y en la ficha de la clase.
Hasta 140 caracteres.
Por ejemplo: lesión de rodilla, usa reformer 3.
app/views/… (la demo de arriba)
<%# En la tarjeta del índice se ve la descripción; en el escenario, también la nota interna de una reservación. %>
<div class="@container w-full max-w-3xl">
<div class="grid gap-x-10 gap-y-5 @xl:grid-cols-2">
<%= render Ui::TextareaComponent.new(name: "class_template[description]", id: "textarea-demo-description", label: "Descripción de la clase",
rows: 3, max_rows: 7, maxlength: 280,
value: "Flujo de vinyasa a ritmo medio: saludos al sol, posturas de pie y un cierre largo de respiración. Trae tu tapete; tenemos bloques y correas.",
hint: "Se muestra en el horario y en la ficha de la clase.") %>
<div class="hidden @xl:block">
<%= render Ui::TextareaComponent.new(name: "reserva[nota]", id: "textarea-demo-note", label: "Nota interna", optional: true,
rows: 2, max_rows: 5, maxlength: 140, placeholder: "Solo la ve el equipo del estudio",
hint: "Por ejemplo: lesión de rodilla, usa reformer 3.") %>
</div>
</div>
</div>Qué hace
- El alto lo lleva el resorte "snappy" de rows a max_rows; se vuelve a medir si cambia el ancho o se resetea el formulario.
- El contador cuenta en vivo en font-mono; cerca del límite (quedan 10% o 10) el número se marca y el anillo pasa a ámbar; al llegar, a rojo.
- Sin JS es un textarea nativo de rows renglones que se puede estirar a mano; el maxlength lo respeta el navegador.
Props
| Nombre | Tipo | Default | Descripción |
|---|---|---|---|
| name | String | nil | Nombre del campo. Con form: + attribute: sale del builder. |
| label | String | nil | Etiqueta visible (sin ella, queda oculta y nombrada por el placeholder). |
| value / placeholder | String | nil | Texto inicial y de ejemplo. |
| rows | Integer | 3 | Renglones con los que empieza (y el alto sin JS). |
| max_rows | Integer | 8 | Hasta dónde crece; después hace scroll. |
| maxlength | Integer | nil | Límite de caracteres: lo respeta el navegador y enciende el contador. |
| form: + attribute: | FormBuilder, Symbol | nil | Nombre, id, valor y error salen del modelo (usa f.text_area). |
| hint / error | String | nil | Ayuda y error (el del modelo se toma solo). |
| required / optional / disabled | Boolean | false | Asterisco, Opcional o deshabilitado. |
| **attrs | Hash | {} | id, data, aria… van al <textarea>; class: se suma a la superficie. |
Accesibilidad
- Etiqueta, ayuda y error enlazados por Field (for, aria-describedby, aria-invalid).
- El límite se lee como descripción ("Hasta 280 caracteres").
- Solo se anuncia (polite) al acercarse al límite y al llegar, no cada letra.