Atajos de teclado (Alt en Windows y Linux, Control en macOS)
Fuente y alcance
Patrón: al mantener una tecla modificadora se muestra una insignia con una letra sobre cada botón y la acción se ejecuta al pulsar modificador + letra; la ayuda de atajos es un diálogo con grupos. Es útil para procesar documentos en lote sin usar el mouse. El resto (insignias, alcance por diálogo, preferencia, reglas por plataforma, asignación y accesibilidad) son decisiones del SGD.
Estado (2026-10-18): primera tanda conectada. El proveedor se monta en el layout del Dashboard (app/dashboard/layout.tsx) y en el portal ciudadano de gov-desk, y hay un botón «Atajos» (ícono de teclado) en la cabecera del Dashboard. Las pantallas con atajos están en el registro de abajo; el resto del sistema se irá sumando poco a poco. La demostración sigue en /design-system/componentes (sección «Atajos de teclado»), que incluye la tabla «Dónde se usa en el sistema» (fuente en código: src/lib/shortcut-registry.ts; mantenerla igual a este registro).
Modificador por plataforma
| Plataforma | Modificador | Mostrar las letras | Ejecutar | Motivo |
|---|---|---|---|---|
| Windows | Alt | Mantener Alt | Alt + letra | No escribe caracteres |
| Linux | Alt | Mantener Alt | Alt + letra | Igual que Windows (se detecta por no ser macOS) |
| macOS | Control | Mantener Control | Control + letra | Option + letra escribe caracteres y Cmd es del navegador |
En macOS, Control + A, B, D, E, F, H, K, L, N, O, P, T, V, Y es la edición de texto estilo Emacs del sistema (MAC_TEXT_FIELD_KEYS). Por eso, mientras el foco está en un campo de texto, esas letras no se interceptan y siguen editando; con el foco fuera de un campo funcionan como atajo. Las demás letras funcionan también dentro de campos. En Windows y Linux no hay esa excepción.
Dónde verlo
En /design-system/componentes, sección «Atajos de teclado» (solo en desarrollo). El selector «Ver como» (Este equipo / Windows y Linux / macOS) cambia el modificador que se muestra y se prueba, sin tener un Mac: con «macOS» se usa Control (insignias, aria-keyshortcuts, ayuda y comportamiento en campos de texto). Debajo hay una tabla de equivalencias entre Windows/Linux y macOS. El selector es solo de la demostración (setShortcutPlatform, useShortcutPlatform); las pantallas reales siempre usan la plataforma detectada.
Componentes
Buttonaceptashortcut="G"(src/components/ui/button.tsx). Añadedata-sgd-shortcut="G"yaria-keyshortcuts="Alt+G"(Control+Gen macOS); sin proveedor no cambia nada más.ShortcutHintsProvider(src/components/ui/shortcut-hints.tsx) escucha el teclado, muestra las insignias y activa el control. Se monta una vez alrededor de la zona donde se quiera la capa.ShortcutsHelp(src/components/ui/shortcuts-help.tsx) es el botón «Atajos» (Alt + I; Control + I en macOS) que abre el diálogo de ayuda: agrupa «En esta pantalla» (los atajos disponibles en ese momento, con el nombre accesible de cada control y sus teclas), «Generales» (modificador, modificador + I, Esc), la nota de la plataforma y el interruptor para desactivar la capa. La lista se lee de los controles conshortcut(listAvailableShortcuts()), por lo que no puede quedar desactualizada ni repetida en otra tabla. Se monta dentro deShortcutHintsProvider, normalmente en la barra de acciones.useShortcutHintsEnabled()devuelve[activado, cambiar]. La preferencia se guarda por navegador (sgd_shortcut_hints_enabled) y por defecto está activada.shortcutModifier()yuseShortcutModifier()devuelven'Alt'o'Control'según la plataforma (el hook dibuja'Alt'en el servidor y corrige tras hidratar).RESERVED_SHORTCUT_KEYS,MAC_TEXT_FIELD_KEYSynormalizeShortcut()documentan y validan las letras.
<ShortcutHintsProvider>
<Button shortcut="G" onClick={guardar}>Guardar</Button>
<Button variant="outline" shortcut="C" onClick={cancelar}>Cancelar</Button>
<ShortcutsHelp />
</ShortcutHintsProvider>
Comportamiento
- Mantener el modificador muestra una insignia con la letra en la esquina superior izquierda de cada control con atajo disponible; soltarlo las oculta. Las insignias se recalculan en cada fotograma mientras el modificador está pulsado, de modo que siguen al control al desplazar, redimensionar o abrir un diálogo.
- Modificador + letra activa el control (
click()). Se usa la tecla física (code), por lo que no depende de la distribución del teclado. Admite letras A–Z y dígitos 0–9. - No se muestran ni actúan los controles deshabilitados, con
aria-disabled, en carga (aria-busy), ocultos o fuera de la ventana. - Alcance por diálogo: con un diálogo o alertdialog abierto solo cuentan los controles de ese diálogo (el de más arriba); la «C» de un modal es independiente de la «C» de la página.
- No actúa con otros modificadores añadidos. Windows y Linux: no con Ctrl, Meta ni Mayús, ni con AltGr (Ctrl + Alt, que escribe caracteres como
@en el teclado español). macOS: no con Alt (Option), Cmd ni Mayús, y los pulsados Control + Mayús o Control + Cmd no se interceptan. - En Windows y Linux, soltar Alt sola cuando la capa estaba visible evita que algunos navegadores activen su barra de menús; Alt + letra usa
preventDefaultsolo si la letra está declarada. - Con la preferencia desactivada la capa no escucha el teclado;
aria-keyshortcutsse mantiene en los controles.
Reglas de asignación
- Una letra por acción visible: en la misma pantalla (o en el mismo diálogo) no se repiten. En desarrollo la consola avisa de repeticiones.
- Primera letra libre de la etiqueta (Guardar → G; Cancelar → C; Nuevo → N). Si choca o está reservada, otra letra de la etiqueta que la recuerde (Firmar → R).
- Evitar las letras del navegador con Alt (Windows y Linux): B, D, E, F, H, S, T, V (menús de Chrome, Edge y Firefox). Se pueden declarar, pero la consola avisa.
- Preferir las letras que no editan texto en macOS (fuera de A, B, D, E, F, H, K, L, N, O, P, T, V, Y) para las acciones que deban funcionar también al escribir; la consola avisa en macOS. «N» (Nuevo) y «P» (Imprimir, por ejemplo) quedan válidas, pero no actúan dentro de un campo en macOS.
- Mismas letras para las mismas acciones en todas las pantallas (la «G» siempre guarda, la «C» siempre cancela, la «I» siempre abre la ayuda). Registrar cada asignación en esta página al incorporarla a una pantalla.
- Declarar atajos solo en acciones primarias de las barras de acciones, no en cada botón.
Apariencia
Insignia <kbd> de 20 px de alto mínimo, Inter 12 px (--sgd-font-help) en negrita, fondo --sgd-tooltip-background y texto --sgd-tooltip-foreground (el mismo par fijo de los tooltips, más de 15:1 en los seis temas y modos), borde de 1 px claro y sombra para distinguirla en modo oscuro, radio de 4 px. Capa fija (.sgd-shortcut-layer, z-index 10000) por encima de modales y tooltips, sin capturar el mouse. No usa animación. En macOS la tecla se muestra como «Control» (no «Cmd»: Cmd + letra es del navegador y del sistema).
Ayuda de atajos
El diálogo usa teclas <kbd> con «+» entre ellas, grupos con título en tipo oración y dos columnas desde 640 px. La lista nunca se escribe a mano: las letras y nombres salen de los controles; con dos controles con la misma letra se muestra el primero (y la consola avisa en desarrollo). El modificador que se muestra es el de la plataforma; en macOS el diálogo explica por qué se usa Control y qué letras siguen editando texto. No incluye una tabla fija «Windows/Linux frente a macOS»: al depender de los controles declarados, se mostraría una sola columna, la de la plataforma actual; la tabla de arriba («Modificador por plataforma») documenta la equivalencia.
Accesibilidad (WCAG 2.2 A + AA)
- 2.1.4 Atajos con carácter: no aplica estrictamente porque el atajo lleva modificador; aun así se ofrece desactivar la capa (
useShortcutHintsEnabled). Si en el futuro se añadiera algún atajo de una sola tecla, sí aplicaría. - 4.1.2: cada control expone
aria-keyshortcuts="Alt+X"(Control+Xen macOS); las insignias sonaria-hidden(ayuda visual, no alternativa del nombre accesible). - 1.4.11 y 1.4.3: insignia con texto de más de 15:1 sobre su fondo y borde claro; se distingue en claro y oscuro.
- 2.4.7 y 2.5.8: no cambia el foco ni el tamaño de los controles.
- 2.5.3 Etiqueta en el nombre: el nombre accesible sigue siendo el texto del botón; la letra no forma parte del nombre.
- Lectores de pantalla: NVDA y JAWS usan Insert o Bloq Mayús como tecla modificadora, no Alt solo, pero no se probó con ellos. En macOS VoiceOver usa Control + Option: Control solo + letra no choca con él, pero hay que probarlo antes de usar la capa en pantallas reales.
Verificación realizada
En /design-system/componentes con Chrome sin interfaz y eventos reales de teclado.
- Windows/Linux (Alt): las insignias aparecen al pulsar Alt y desaparecen al soltarla; Alt + G y Alt + N ejecutan sus acciones; Ctrl + Alt + N (AltGr) y Alt + X (deshabilitado) no hacen nada; con el modal abierto solo se muestran y actúan las del modal (Alt + C cancela el modal, no la «C» de la página); con la preferencia desactivada no hay insignias; Alt + I abre la ayuda con la lista exacta de la pantalla y Esc la cierra; axe (WCAG 2 A/AA, 2.1 AA, 2.2 AA) sin violaciones en la sección con y sin Alt y en el diálogo, en claro y oscuro.
- macOS (plataforma emulada
MacIntel):aria-keyshortcutsconControl+X; con Alt pulsada no aparecen insignias y Alt + G no hace nada; con Control pulsada aparecen; Control + G ejecuta; Control + Mayús + G y Control + Cmd + R no actúan; Control + N fuera de un campo ejecuta y dentro de un campo de texto no se intercepta, mientras Control + G y Control + R sí actúan dentro del campo; la ayuda muestra «Ctrl» y Control + I la abre. - Selector «Ver como»: «macOS» muestra y ejecuta con Control (Alt no); «Windows y Linux» vuelve a Alt; axe sin violaciones en toda la sección (incluida la tabla), en claro y oscuro.
tsc, ESLint yicons:checksin errores.
No probado
Un Mac real y un Linux real (macOS se probó con la plataforma emulada, sin las reglas reales del sistema; Linux se asume igual que Windows), Firefox, Safari y Edge, conflictos reales con el navegador o el sistema (por ejemplo atajos globales de Mission Control o de escritorios Linux), lectores de pantalla (NVDA, JAWS y VoiceOver), teclados distintos del español y pantallas reales del Dashboard (no hay atajos declarados). Antes de conectarla al layout (y de añadir el botón «Atajos» a la barra de acciones), definir la lista de atajos por pantalla y comprobar estos puntos.
Registro de atajos (fuente de verdad)
Cada atajo nuevo se registra aquí antes de declararse en una pantalla. Una letra por acción visible en la misma pantalla; las mismas acciones usan la misma letra en todo el sistema. En macOS se usa Control en lugar de Alt (no Cmd).
| Letra | Acción | Dónde (SGD) | Dónde (gov-desk, portal ciudadano) |
|---|---|---|---|
| G | Grabar o actualizar | Todos los diálogos con formulario, también en administración (botón de envío, Guardar, Crear, Actualizar, Registrar, Aplicar, Agregar, Asignar, Enviar, Importar o Generar; automático); formulario de documento («Grabar»); revisión de visto bueno («Guardar nota»); registro de Mesa de partes («Grabar»); edición de un registro de Mesa de partes («Actualizar») | |
| N | Nuevo | Emisión de documentos y Documentos en Proyecto («Nuevo»); bandeja de Mesa de partes («Nuevo»); páginas de administración («Nueva oficina», «Nuevo rol», etc.: el primer botón de creación de cada página) | Menú «Registrar documento» |
| R | Generar, registrar o recibir | Formulario de documento («Generar», antes de generar; después el botón pasa a «Editar» y no lleva atajo); edición de Mesa de partes («Registrar documento»); revisión de un documento recibido («Recibir») | |
| C | Cargar o cancelar | Todos los diálogos («Cancelar», automático); formulario de documento («Cargar»); edición de Mesa de partes («Cargar documento»); registro de Mesa de partes («Cancelar»); ventana de firma («Cancelar») | Buzón: «Notificaciones» |
| A | Abrir o ver el documento | Formulario de documento («Abrir» / «Ver Documento»); revisión de visto bueno («Ver documento»); edición de Mesa de partes («Ver documento») | Buzón: «Archivado» |
| X | Anexos | Formulario de documento («Cargar anexos» en proyecto, «Ver anexos» después); revisión de visto bueno («Ver anexos»); edición de Mesa de partes («Cargar anexos» al editar, «Ver anexos» después) | |
| M | Firmar o visar (SGD) / Mis documentos (portal) | Formulario de documento («Firmar»); revisión de visto bueno («Visar documento»); ventana de firma («Firmar», «Emitir») | Menú «Mis documentos» |
| O | Observar / Más filtros | Revisión de visto bueno («Observar»); tablas con filtros avanzados («Más filtros») | |
| Q | Ir al buscador de la tabla (enfoca el campo) | Todas las tablas con buscador y los filtros de las páginas de administración | |
| U | Actualizar la lista | Casilla («Actualizar») | |
| L | Cargar más | Casilla («Cargar más») | |
| Y | Grabar y enviar a verificar / Destacados | Registro de Mesa de partes («Grabar y enviar a verificar») | Buzón: «Destacados» |
| I | Abrir la ayuda de atajos | Cabecera del Dashboard y de administración (botón «Atajos») y demostración |
Sin atajo a propósito: las acciones destructivas (Anular, Eliminar), para que no se activen por error. Los atajos también pueden llevar el cursor a un campo de texto (Q: buscador de las tablas): la capa enfoca el campo y selecciona su contenido en lugar de pulsarlo. Pendiente de definir: acciones de las demás bandejas (Para firma, En proyecto, Recibidos, Enviados), Responder, Observar y Archivar en recepción, y Mesa de partes: consulta y cargo.
gov-desk: usa una copia de shortcut-hints.tsx y la propiedad shortcut de su Button; mantener ambas iguales a las del SGD. Aún no tiene la ayuda de atajos (no tiene Dialog).
Automático en diálogos: DialogContent asigna al abrirse C a «Cancelar» y G al botón de envío o al que empieza por Guardar, Crear, Actualizar, Registrar, Aplicar, Agregar, Asignar, Enviar, Importar o Generar dentro de su pie (dialog-footer), sin pisar un atajo ya declarado. Las confirmaciones (AlertDialog) no lo usan: Enter y Esc bastan. Los campos de texto aceptan shortcut (<Input shortcut="Q">).