Button
Botones en todas las variantes y tamaños, con un flujo integrado de carga, éxito y error que omite el spinner en las peticiones rápidas.
pnpm dlx shadcn@latest add https://hextaui.com/r/button.jsonAñade el componente, los tokens del tema de HextaUI y los componentes de HextaUI de los que depende.
Añade los tokens del tema a tu CSS global, si aún no lo has hecho.
Instala las dependencias.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cnCopia y pega el siguiente código en tu proyecto.
components/ui/button.tsx Actualiza las rutas de importación para que coincidan con la configuración de tu proyecto.
Con feedback, devuelve una promesa desde onClick y el botón muestra la carga, luego el éxito o el error, y después se reinicia por sí solo.
Variantes
Siete variantes. destructive es un tinte suave para que una acción peligrosa se lea con claridad sin gritar, y ghost-destructive es la versión discreta para acciones de fila repetidas como Sign out o Remove.
Tamaños
Tamaños de texto de xs a lg, y tamaños cuadrados icon-*. Los botones de icono pequeños obtienen un área táctil invisible mayor en pantallas táctiles.
Píldora
shape="pill" redondea los extremos por completo, y los tamaños de icono se vuelven círculos. Va bien en botones que están dentro de superficies redondeadas, como un compositor de chat.
Con icono
Marca un icono con data-icon="inline-start" o "inline-end" y el relleno de ese lado se reduce para equilibrarlo.
Deshabilitado
focusableWhenDisabled mantiene un botón deshabilitado en el orden de tabulación, de modo que un tooltip o una explicación sigan siendo accesibles con el teclado.
Etiquetas personalizadas
loadingLabel, successLabel y errorLabel reemplazan el texto de cada estado. Cada etiqueta entra con un giro mientras la anterior sale con otro.
Ancho suave
El botón se ajusta suavemente al ancho de cada etiqueta en lugar de reservar espacio para la más larga, así que nada a su alrededor salta.
Detalles del error
Pasa una función a errorLabel para mostrar el motivo del rechazo. Mientras el puntero o el foco del teclado permanezcan en el botón, el error se mantiene en pantalla.
Formularios
Para los botones de envío, llama a track() de useButtonFeedback en onSubmit y esparce buttonProps en el botón. Quita la @ para ver el error.
Botones de icono
Los tamaños de icono solo cambian el icono en cada estado y conservan su forma cuadrada. El aria-label sigue siendo el nombre accesible.
Feedback en cada variante
Las variantes rellenas pasan a verde o rojo al terminar. ghost y link solo cambian el color del texto.
Carga controlada
Define loading tú mismo cuando el trabajo se rastree en otro lugar. El botón sigue pudiendo recibir foco y anuncia que está ocupado.
Estado controlado
Controla status directamente, por ejemplo desde el estado de envío de una librería de formularios.
Como enlace
Pasa un ancla a render y define nativeButton={false} para que el botón conserve la semántica de enlace.
De derecha a izquierda
Los iconos y las etiquetas de estado siguen la dirección de lectura.
| Key | Acción |
|---|---|
| EnterSpace | Activa el botón. Se ignora mientras hay una petición de feedback en curso. |
| Tab | Mueve el foco. Un botón en carga sigue pudiendo recibir foco, y enfocar un error lo mantiene en pantalla hasta que te muevas. |
- Cada cambio de estado se anuncia mediante una región activa polite: primero la carga y luego la etiqueta de éxito o de error.
- Durante la carga, el botón define
aria-busyy sigue pudiendo recibir foco, así que el foco nunca se pierde a mitad de la petición. - El spinner aparece solo después de 150 ms y luego permanece al menos 400 ms, así que las peticiones rápidas nunca lo muestran por un instante y las lentas nunca parpadean.
- Con movimiento reducido, las etiquetas de estado se desvanecen en lugar de voltearse y se omite la sacudida del error.
Construido sobre el botón de Base UI. Renderiza un <button> y acepta todos sus atributos.
| Prop | Tipo | Predeterminado |
|---|---|---|
variant | "default" | "outline" | "secondary" | "ghost" | "ghost-destructive" | "destructive" | "link" | "default" |
size | "xs" | "sm" | "default" | "lg" | "icon-xs" | "icon-sm" | "icon" | "icon-lg" | "icon-xl" | "default" |
shape | "default" | "pill" | "default" |
feedbackRastrea la promesa devuelta por onClick y muestra su estado. | boolean | false |
onClickDevuelve una promesa para controlar el feedback. | (event) => unknown | – |
loadingEstado de carga controlado. | boolean | – |
statusEstado controlado. Tiene prioridad sobre loading. | "idle" | "loading" | "success" | "error" | – |
onStatusChange | (status: ButtonStatus) => void | – |
onErrorSe llama con el motivo del rechazo. | (error: unknown) => void | – |
resetAfterMilisegundos antes de volver al estado de reposo. | number | { success?: number; error?: number } | { success: 2000, error: 4000 } |
loadingLabelSe muestra junto al spinner. Oculto en los tamaños de icono. | ReactNode | – |
successLabel | ReactNode | "Done" |
errorLabel | ReactNode | (error: unknown) => ReactNode | "Failed" |
disabled | boolean | false |
focusableWhenDisabledSiempre true durante la carga. | boolean | false |
nativeButtonPonlo en false cuando render no sea un <button>. | boolean | true |
render | ReactElement | (props, state) => ReactElement | <button> |
| Atributo | Descripción |
|---|---|
data-slot="button" | Selecciona los botones en CSS. |
data-status | idle, loading, success o error. Presente una vez que se usa feedback, loading o status. |
data-disabled | Presente cuando el botón está deshabilitado. |
aria-busy | Presente durante la carga. |
Ejecuta el mismo flujo de feedback desde cualquier lugar, como el onSubmit de un formulario. Acepta resetAfter, onStatusChange y onError. Consulta la guía de useButtonFeedback para ver los tiempos completos.
| Devuelve | Descripción |
|---|---|
track(action) | Pasa una promesa o una función que devuelva una. Las llamadas mientras hay una petición en curso se ignoran. |
buttonProps | Espárcelo en <Button> para mostrar el estado y pausar el reinicio al pasar el cursor y al recibir foco. |
status | El ButtonStatus actual. |
error | El último motivo de rechazo. |
reset() | Cancela la petición y vuelve al estado de reposo. |
isPending() | Si hay una petición en curso. |
- SpinnerUn indicador de carga con marcas al estilo Apple o un anillo que respira, que puede esperar antes de mostrarse y permanecer el tiempo suficiente para no parpadear.
- useButtonFeedbackEjecuta 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.
- Button groupBotones unidos en un solo control, con uniones compartidas, separadores, addons de texto, anidamiento y apilados verticales.
- ToggleUn botón que se mantiene activado o desactivado, con un relleno que se asienta al pulsar, un paso claro de hover a activado e iconos que pueden rellenarse según el estado.
- Toggle groupUna fila de toggles para una o varias opciones, con un relleno que se desliza hasta el elemento elegido, elementos unidos o separados y foco con las teclas de flecha.
- AlertMensajes en línea para estado y comentarios, con una superficie neutra, un icono de color y un descarte que se colapsa con suavidad.
Usado en bloques
Bloques que se construyen sobre Button.
- Prompt InputUn compositor de chat que empieza como una línea tranquila, crece hasta convertirse en una tarjeta mientras escribes y baja cuando empieza la conversación. Enter envía, de forma segura con entrada en japonés y chino. Pega, suelta o elige archivos con vistas previas, progreso y reintento. @ añade archivos y / ejecuta comandos desde un menú junto al cursor. Un selector de modelo con teclas numéricas, un control deslizante de esfuerzo que cobra vida en Max, un anillo de contexto, dictado con forma de onda en vivo, chips de herramientas, una cola para los mensajes escritos mientras se transmite una respuesta y borradores que sobreviven a una recarga.
- Agent TodosMuestra el plan de un agente mientras trabaja. Cada paso pasa de pendiente a por hacer, en curso y hecho, con tiempos en vivo, fallos y las llamadas a herramientas detrás. Una píldora de estado para sobre el compositor, cambios del plan que puedes ver y un paso de revisión para editar el plan antes de ejecutarlo.
- API keysLa página de claves de API de un producto de IA, como las consolas de OpenAI y Anthropic. Crea claves con permisos acotados y caducidad, ve el secreto una sola vez con una copia que lo confirma, revoca con deshacer, renombra en el sitio, rota con un periodo de gracia y consulta el uso por clave.
- AppearanceLa sección Apariencia de los ajustes de un producto de IA: tema, acento, tinte de fondo, densidad, fuente del chat, tamaños de texto y opciones de accesibilidad, todo guardado como borrador hasta que se guarda.