Botones del SGD
Primera familia del Design System del SGD. La página de revisión está en /design-system/componentes durante desarrollo. Reutilizar Button de src/components/ui/button.tsx; no crear botones de marca locales. Los ejemplos de las capturas son referencias visuales, no una especificación de código.
Lo observado en las 19 capturas
| Capturas | Componente y estados visibles | Límites de la referencia |
|---|---|---|
| 1–3 | “Confirmar datos”: contorno rojo; relleno rosa rojizo; relleno rojo oscuro. | La secuencia sugiere reposo, hover y activación, pero la captura no rotula los estados. |
| 4–6 | “Ir a la página de inicio”: contorno rojo, fondo rosa tenue y relleno rojo con contorno azul separado. | El último parece foco; no hay token ni medida de grosor documentados. |
| 7–9 | “Prefiero uno aleatorio”: texto neutro, fondo gris tenue y contorno azul de foco. | No se muestra estado deshabilitado. |
| 10–11 | Primario “Agregar”, con y sin icono; versión pálida deshabilitada. Galería rotulada: base, carga, peligro, terciario, ghost y enlace. | “Cargando” es visible, pero la captura no prueba si bloquea clics. |
| 12 | Galería azul: primario, secundario, terciario, ghost y enlace. Iconos a la izquierda de algunas etiquetas. | No define estados de interacción de todas las variantes. |
| 13–14 | Botones blancos de relleno, contorno y enlace sobre superficie índigo. | No hay indicación de comportamiento responsive. |
| 15–19 | Hover y foco de Cancelar, enlace inverso, contorno inverso y sólido inverso. | La etiqueta de cada estado se deduce de la secuencia visual. |
Los recortes muestran esquinas moderadamente redondeadas, bordes finos, etiquetas centradas y peso semibold. El foco parece un contorno azul separado del borde. El pixelaje o compresión de las capturas impide derivar valores exactos de fuente, radio o color. Sus fondos rojos/azules se traducen al token primary de cada tema; peligro conserva destructive y no adopta el color de marca.
API y jerarquía
| Necesidad | variant | Uso |
|---|---|---|
| Acción dominante | default | Una acción principal por sección. |
| Marca de contorno | brandOutline | Acción secundaria reconocible. |
| Texto de marca | brandTertiary | Utilidad ligera sin contenedor. |
| Ghost de marca | brandGhost | Utilidad con fondo tenue en hover. |
| Enlace visual | brandLink | Acción de navegación con texto subrayado; si navega, usar asChild con Link. Ver «Variante enlace». |
| Peligro | dangerOutline o destructive | Acción destructiva explícita. Añadir verbo y, cuando ayude, icono. |
| Peligro en línea | dangerTertiary | Confirmar una acción menor y reversible dentro de una fila o lista (p. ej. eliminar un favorito de filtros): texto de peligro sin relleno ni borde, subrayado solo al pasar el mouse. Acompañar de brandTertiary para «Cancelar». Para acciones graves o irreversibles usar destructive en un diálogo. |
| Neutro | ghost, outline, secondary | Alternativas existentes sin énfasis de marca. |
| Sobre superficie de identidad | inverse, inverseOutline, inverseLink | Solo en un contenedor con --sgd-inverse-surface. |
size="default" da altura mínima de 40 px; sm 36 px y lg 44 px. La tipografía es Inter a 14 px y el radio de control es 6 px. Los iconos son Icon de Material Symbols Rounded, normalmente 18 px. El espaciado entre icono y texto es 8 px. La geometría no cambia entre Theme LATAM, Theme Adobe Spectrum y Theme Institucional ni entre modos. Las claves guardadas siguen siendo latam, azul y gobpe.
import { Button } from '@/components/ui/button'
import { Icon } from '@/components/ui/icon'
<Button><Icon name="add" size={18} />Nuevo documento</Button>
<Button variant="brandOutline">Descargar</Button>
<Button variant="dangerOutline"><Icon name="delete" size={18} />Eliminar</Button>
<Button loading loadingText="Guardando">Guardar</Button>
Tokens
primaryyprimary-foreground: acción de marca y su texto. Cada paleta aporta su valor.accent: superficie tenue de hover o selección de marca.destructive: peligro, independiente de la marca.--sgd-danger-outline: texto y borde de peligro legibles también en modo oscuro.--sgd-button-focus: anillo visible en claro y oscuro. Se mantiene azul por accesibilidad y continuidad con las capturas, también en Theme Institucional.--sgd-inverse-surface,--sgd-inverse-foreground,--sgd-inverse-button,--sgd-inverse-button-hover,--sgd-inverse-button-foreground,--sgd-inverse-hover: combinación de alto contraste sobre superficie de identidad.--sgd-control-height,--sgd-control-height-compact,--sgd-radius-control,--sgd-font-body: medidas compartidas.
Los tokens viven en src/app/globals.css. No fijar hexadecimales dentro de componentes ni de pantallas. La página de muestras cambia las preferencias reales mediante useColorTheme y next-themes para verificar las seis combinaciones.
Estados y accesibilidad
| Estado | Regla del SGD | Procedencia |
|---|---|---|
| Normal | Fondo, borde o texto según jerarquía. | Observado. |
| Hover | Cambio de superficie/color sin mover el control. | Observado parcialmente; transición propuesta. |
| Foco | Contorno de 2 px separado 2 px, activado por teclado. | Contorno observado; medidas propuestas. |
| Seleccionado | aria-pressed y marca/icono además del color. | Propuesto; las capturas no muestran un toggle. |
| Deshabilitado | disabled nativo, sin acción ni foco. | Apariencia observada; semántica propuesta. |
| Carga | loading, aria-busy, bloqueo de clic y texto de progreso. | Apariencia observada; comportamiento propuesto. |
| Error | No es una variante genérica de botón. El mensaje de error se presenta junto al formulario o notificación. | Propuesto. |
Para enlaces reales, usar Button asChild con Link o <a> y un nombre accesible. No combinar loading con asChild; el estado de carga está diseñado para el botón nativo. En botones de solo icono, añadir aria-label: el componente usa esa etiqueta (o el title existente) para el tooltip compartido y evita el title nativo duplicado. Para acciones seleccionables, aria-pressed debe reflejar el estado real. Respetar movimiento reducido en la animación del indicador de carga.
Variante enlace (brandLink, inverseLink)
dangerTertiary (y brandTertiary) son los terciarios de texto: sin relleno, sin borde y sin subrayado en reposo; el subrayado (1 px, separado 4 px) aparece solo con el mouse encima, mediante una regla plana en globals.css. Así una fila con dos acciones, como la confirmación de «Eliminar» de un favorito de filtros (filter-panel.tsx), no se ve cargada: la pregunta ocupa todo el ancho y, debajo y a la derecha, «Cancelar» (brandTertiary) y «Eliminar» (dangerTertiary), en semibold. El texto de peligro usa --sgd-danger-outline, legible en claro y oscuro.
Botón de texto subrayado con icono direccional (arrow_forward) o externo (open_in_new), antes o después del texto. Referencia: «Continuar →» (Theme LATAM/Adobe Spectrum, índigo/azul) y «Ver más ⧉» (Theme Institucional, rojo), con su hover de fondo tenue.
- El subrayado cubre solo el texto, de la primera a la última letra.
Buttonenvuelve cada tramo de texto de los hijos en<span class="sgd-link-text">(conasChildlo hace dentro del<a>/Link) y la clase aplicatext-decoration: underline(1 px,text-underline-offset: 4px). El botón no llevaborder-bottomnitext-decoration, así que el icono y el hueco icono–texto (gap-2, 8 px) quedan sin subrayar. Los espacios en los extremos del texto se recortan. Si el contenido es más complejo que texto plano (<strong>, etc.), envolver ese tramo en<span className="sgd-link-text">. - Hover (regla plana en
globals.css, no depende de@media (hover)): fondo--accent(brandLink) o--sgd-inverse-hover(inverseLink) sobre todo el botón (texto + icono + relleno). Solo cambia el color de fondo: sin cambios de tamaño, posición ni transformaciones (medido: caja del botón y del texto idénticas antes y después). - Clic y cursor en toda el área del botón (
cursor: pointer); el icono es hijo del botón, así que el clic sobre él también activa el botón. - Foco por teclado: contorno de 2 px con separación de 2 px (
--sgd-button-focus), alrededor de todo el botón. - Deshabilitado:
disablednativo (oaria-disabledconasChild): 50 % de opacidad, sin hover, sin acción; conaria-disabledel cursor esnot-allowed. - Temas: el color sale de
primaryy el hover deaccentde cada paleta, en claro y oscuro (verificado Theme LATAM, Theme Adobe Spectrum e Institucional en claro, y LATAM e Institucional en oscuro). Peso semibold. Mantener un nombre accesible en el texto; el icono es decorativo.
<Button asChild variant="brandLink"><Link href="/x"><Icon name="arrow_forward" size={18} />Continuar</Link></Button>
<Button asChild variant="brandLink"><a href="…">Ver más<Icon name="open_in_new" size={18} /></a></Button>
Hover de botones de fondo suave: ghost, outline, brandGhost y brandOutline cambian a --accent al pasar el mouse mediante una regla plana en globals.css ([data-sgd-button][data-variant="…"]:hover; Button expone data-variant). No se confía solo en hover: de Tailwind: esa variante va dentro de @media (hover: hover) y los equipos que reportan hover: none (algunos táctiles o híbridos, y el navegador de pruebas) nunca la activan. El cursor es de mano, el hover no cambia tamaño ni desplaza el contenido, un botón deshabilitado no reacciona y el foco visible por teclado (focus-visible, contorno de 2 px) no se altera. Los botones de acción dentro de listas, como «Guardar búsqueda como favorito» o «Criterios avanzados…» del desplegable de filtros, usan variant="ghost": no crear estilos locales de hover.
Las clases sgd-button-demo-* existen solo para representar estados estáticos en la página de revisión; no deben copiarse a funcionalidades del SGD. Los botones de la página también son operables y permiten verificar hover, foco real con Tab, deshabilitado y selección.
Próximos componentes
La página se ampliará progresivamente al recibir capturas de inputs, selectores, menús, pestañas y tablas. La primera entrega no cambia la distribución de las pantallas de trabajo.