Formularios

Estado: Beta

Selector numérico

Capacidad de una clase, duración, créditos o la cantidad del carrito. Es un input numérico real (con su name, min, max y step) con botones de − y +: mantener presionado repite cada vez más rápido, los dígitos ruedan hacia arriba al sumar y hacia abajo al restar, y al llegar a un límite el botón se apaga y el número rebota. Dispara input y change reales, así que el carrito y cualquier otro controlador se enteran solos.

De 1 a 40 por clase

En pasos de 15

Tapete de corcho

$890 · quedan 5

app/views/… (la demo de arriba)

<div class="@container w-full max-w-md">
  <div class="grid gap-5">
    <div class="grid gap-4 @sm:grid-cols-2">
      <%= render Ui::NumberStepperComponent.new(label: "Capacidad", name: "studio_class[capacity]", value: 12, min: 1, max: 40,
            unit: "lugares", full_width: true, hint: "De 1 a 40 por clase") %>
      <%= render Ui::NumberStepperComponent.new(label: "Duración", name: "studio_class[duration]", value: 60, min: 15, max: 180, step: 15,
            unit: "min", full_width: true, hint: "En pasos de 15") %>
    </div>

    <div class="flex items-center gap-3 rounded-xl border border-border bg-card p-3">
      <span class="hidden size-11 shrink-0 place-items-center rounded-lg border border-border-subtle bg-raised text-subtle @sm:grid" aria-hidden="true">
        <%= render Ui::IconComponent.new(:package, size: :lg) %>
      </span>
      <div class="min-w-0 flex-1">
        <p class="truncate text-sm font-medium text-foreground">Tapete de corcho</p>
        <p class="font-mono text-xs text-muted-foreground">$890 · quedan 5</p>
      </div>
      <%= render Ui::NumberStepperComponent.new(label: "Cantidad de tapetes", hide_label: true, name: "quantity", value: 1, min: 1, max: 5, size: :sm) %>
    </div>
  </div>
</div>

Qué hace

  • Mantener presionado repite con aceleración (de 150 a 40 ms por paso).
  • Cada cifra rueda con su resorte en la dirección del cambio, también de 9 a 10.
  • En el mínimo o el máximo el botón se deshabilita y el valor da un rebote.
  • Lo escrito a mano se lleva al paso y al rango válidos al salir del campo.
  • Dispara input (cada paso), change (al soltar o por tecla) y number-stepper:change.

Props

Nombre Tipo Default Descripción
label String — Etiqueta del campo (Ui::FieldComponent); también nombra al spinbutton.
name String nil Nombre del input. Con form + attribute sale del form builder.
form / attribute FormBuilder / Symbol nil Toma name, id, valor y error del modelo.
value Numeric nil Valor inicial (con form, el del modelo).
min / max / step Numeric nil / nil / 1 Los del input nativo. Los pasos cuentan desde min.
unit String nil Unidad junto al número ("min", "lugares"); se lee con el valor.
size :sm | :md :md :sm para filas compactas como el carrito.
full_width Boolean false Ocupa todo el ancho de la columna.
hint / error / required / hide_label — — Los de Ui::FieldComponent.
input Hash {} Atributos extra del input (data, autofocus…).

Accesibilidad