useButtonFeedback
Ejecuta una acción asíncrona pasando por carga, éxito y error, omitiendo el spinner en peticiones rápidas y manteniendo un error mientras lo lees.
pnpm dlx shadcn@latest add https://hextaui.com/r/use-button-feedback.jsonAñade el hook y todo lo que necesita a tu proyecto.
Copia y pega el siguiente código en tu proyecto.
hooks/use-button-feedback.ts Actualiza las rutas de importación para que coincidan con la configuración de tu proyecto.
<Button feedback> ejecuta este flujo por ti cuando su onClick devuelve una promesa. Usa el hook cuando el trabajo empieza en otro sitio, como el onSubmit de un formulario, un atajo de teclado o un blur. También sirve cuando el estado pertenece a algo que no es un botón.
track() acepta una promesa, o una función que devuelva una, y mueve status por idle, loading, luego success o error, y de vuelta a idle. Los tiempos son lo que lo hace sentir tranquilo.
| Paso | Descripción |
|---|---|
0–150ms | El estado permanece en idle. Una petición que se resuelve en esta ventana pasa directamente a success o error, sin spinner. |
loading | Se muestra a partir de 150ms. Una vez mostrado dura al menos 400ms, así que nunca aparece de golpe. |
success | Se mantiene 2 segundos por defecto y luego vuelve a idle. |
error | Se mantiene 4 segundos por defecto. Mientras el puntero está sobre el botón, o este tiene el foco del teclado, el reinicio espera a que se vayan, más 600ms. |
- Las llamadas a
track()mientras hay una petición en curso se ignoran, así que un doble clic o una tecla Enter mantenida nunca envían la petición dos veces. - Una función pasada a
track()que lanza un error de forma síncrona se trata como una promesa rechazada. reset()vuelve a idle de inmediato. Lo que haga más tarde la petición abandonada se ignora, igual que cualquier cosa que se resuelva después de desmontar el componente.- La retención del error solo cuenta un hover real del ratón y el foco del teclado. El táctil no tiene hover, y el foco de un clic no es
:focus-visible, así que ninguno de los dos fija el error.
Formularios
Llama a track() desde onSubmit y expande buttonProps en el botón de envío. Quita la @ para ver el error.
Estado sin un botón
Lee status para controlar cualquier UI. Esta nota se guarda al perder el foco y muestra el resultado a su lado, en una región role="status" que los lectores de pantalla anuncian.
resetAfter acepta un solo número para ambos resultados, o un objeto para definir cada uno. error contiene el último motivo de rechazo, para que puedas mostrarlo en la etiqueta, como hace el ejemplo de detalles de error de Button.
- Dale a cada botón su propio hook. Dos botones que compartan un
buttonPropsmuestran el mismo estado. onStatusChangeyonErrorsiempre llaman a la última función que pasaste, así que las funciones en línea están bien.- Usa
isPending()para proteger trabajo fuera detrack(). Lee un ref, así que es preciso incluso antes del siguiente renderizado.
| Prop | Tipo | Predeterminado |
|---|---|---|
resetAfterCuánto tiempo permanecen success y error antes de volver a idle. | number | { success?: number; error?: number } | { success: 2000, error: 4000 } |
onStatusChangeSe llama en cada cambio de estado. | (status: ButtonStatus) => void | – |
onErrorSe llama con el motivo del rechazo. | (error: unknown) => void | – |
| Propiedad | Descripción |
|---|---|
track(action) | Pasa una promesa o una función que devuelva una. Se ignora mientras hay una petición en curso. |
buttonProps | status más manejadores de puntero y foco. Expándelo en <Button>, o en cualquier cosa que componga esos manejadores. |
status | "idle" | "loading" | "success" | "error" |
error | El último motivo de rechazo. |
reset() | Vuelve a idle ahora e ignora la petición en curso. |
isPending() | Si hay una petición en curso. |
Button mediante su prop feedback.