Input · type=text
El campo de entrada es el lugar donde el sistema acepta o rechaza al usuario. Su contrato no es solo visual: es semántico, accesible, validado en cliente y en servidor, idiomático en cada locale, y resistente a autocompletado de gestores externos. Esta ficha documenta el estado del Input texto en mayo de 2026.
Decomposición del componente
Las seis capas del componente
01 · Átomo color.neutral.950 · color.red.500 · space.10 · space.14 · radius.sm · duration.120 Primitivos: colores de texto y borde, anchuras de padding, radio suave para inputs, duración base de transición. Ningún input del sistema inventa valores propios.
02 · Compuesto color.surface.input.bg · color.text.input.fg · color.border.input.default · color.border.input.focus · space.input.x · space.input.y Semánticos con intención. El Input los consume como alias, nunca como hexadecimales. Agente tier-2 puede mutarlos dentro del espacio declarado; nunca salta a primitivos.
03 · Regla Zod schema dual cliente/servidor · contrato de autocompletado · aria-invalid dosificado · auditoría cross-SR Governance ejecutable. La validación vive en una única fuente y se compila a JSON Schema para el backend; la semántica de autocomplete se cierra sobre el enum de valores estándar WHATWG.
04 · Pieza <Input type='text' schema={...} autocomplete='given-name' /> Componente con props estables y schema cerrado sobre valores semánticos HTML5 válidos. Cualquier autocomplete fuera del enum se rechaza en CI.
05 · Familia Inputs / Form fields (9 componentes hermanos) Comparte tokens de borde, focus y padding con Select, Checkbox, Radio, Toggle, Textarea, DatePicker, NumberInput, FileInput. Diferencia: el Input texto admite el espectro más amplio de valores semánticos del formulario.
06 · Estado reposo · hover · focus-visible · readonly · invalid · loading · disabled · agent-aware Comportamientos temporales. invalid es el estado más catalogado del sistema: nueve variantes de error con mensaje accesible específico.
Tokens consumidos
Semánticos
color.surface.input.bg oklch(0.99 0.005 75) Fondo en reposo, contraste suave sobre superficie del formulario
color.text.input.fg oklch(0.18 0 0) Texto del usuario, contraste AAA verificado
color.border.input.default oklch(0.78 0.005 75) Borde en reposo, 1.5px
color.border.input.focus oklch(0.53 0.18 26 / 0.7) Borde en focus visible, halo opcional 4px
space.input.x 0.875rem Padding horizontal
space.input.y 0.625rem Padding vertical, hit-target mínimo 44px combinado con line-height
Técnicas de governance aplicadas
Técnicas activas
Validación dual
El esquema vive en una sola fuente y se compila a JSON Schema para servidor. Sin replicación manual: el contract es el mismo en frontend y backend.
Autocompletado idiomático
email, given-name, family-name, address-line1, postal-code, etc. El campo declara su semántica para que el navegador y los gestores de contraseñas lo reconozcan correctamente.
Mensajería accesible de error
El error se anuncia al lector de pantalla solo cuando se confirma (blur o submit), no en cada keystroke. La regla evita el ruido y respeta SC 4.1.3.
Estado físico
Agentic-consumable desde noviembre de 2025. El Input expone vía MCP los tres atributos que un agente necesita conocer para construir un formulario válido: tipo semántico, schema de validación, y mensajes de error en español.
Estados soportados
hover, focus-visible, disabled, readonly, invalid, loading (estado intermedio durante validación asíncrona), agent-aware. El estado loading es deliberadamente sutil: un borde tenue animado que no compite con el contenido.
Composiciones prohibidas
Reglas activas
type HTML5 inventado
Un agente puede proponer type='phonenumber' o type='creditcard'. Ninguno existe en HTML5. La policy rechaza con mensaje: 'usar type=tel o type=text con pattern; el input canónico no amplía el enum'.
Validación en keystroke
Validar en cada tecla genera ruido cognitivo y bloquea el flujo. La policy solo permite validación on-blur y on-submit. Propuestas on-keystroke devuelven warning con la alternativa.
Label ausente o vacío
Input sin label asociado o con label vacío se rechaza. Placeholder no cuenta como label. Alternativa: aria-label si la composición visual no permite label explícito.
Autocomplete fuera del enum estándar
autocomplete='my-custom-field' se rechaza. El agente recibe el listado válido y se le pide que asigne el más próximo o marque autocomplete='off' si no hay match.
Interoperabilidad
- Consumido por:
FormRow,FieldGroup,InlineSearch,ModalForm,SettingsPanel. Cada padre define el spacing vertical y la política de error (inline vs tooltip). - Consume:
Label(obligatorio, asociado por for/id),HelperText(opcional, aria-describedby),ErrorMessage(condicional, aria-invalid). - Con qué compone mal: dentro de
Tooltip(un input que vive en tooltip pierde foco al cerrarse), dentro deToast(efímero incompatible con escritura). Alternativa:Popovercon Input dentro, oDrawerpara edición extendida. - Sustituibles por:
Textareasi el contenido esperado supera 80 caracteres,NumberInputsi es numérico,DatePickersi es fecha,Comboboxsi hay sugerencias.
Medición propuesta
Eventos planificados
input.focus
Atributos: type, ruta, position en formulario, origin (humano | agente). Permite detectar inputs que reciben foco pero no input event (fricción de entrada).
input.validation_error
Atributos: tipo de error (pattern, longitud, requerido, formato), count por sesión. Detecta patrones de mensaje de error que el usuario no entiende.
input.autocomplete_hit
Agregado por valor semántico (email, given-name, postal-code). Los campos con tasa de autofill baja suelen tener semántica mal declarada.
Mutación plástica (Estado 3)
Qué muta y qué permanece
Teclado virtual inputmode = derive(locale × device) En mobile el inputmode ajusta el teclado (numeric, tel, email, search). Se deriva de type semántico y locale del navegador; nunca se hardcodea en la composición.
Autocapitalización autocapitalize = derive(type × locale) Idiomas sin casos (japonés) desactivan autocapitalize; idiomas con mayúscula al inicio (español) la activan según el tipo semántico.
Mensajes de error tono = derive(severidad × prefers-reduced-motion) Con reduced-motion, el mensaje aparece sin slide-in. La severidad ajusta el phrasing: validación ligera usa infinitivo (corregir); bloqueante usa imperativo (complete el campo).
Density del padding space.input.y = derive(viewport × pointer × density-pref) Touch amplía padding vertical; desktop lo compacta. Si hay user-pref de densidad, se respeta por encima del default.
Fijo por contract schema Zod · autocomplete enum · label asociado · aria-invalid Nunca mutan. El agente no puede aflojar el schema, inventar autocompletes, quitar label asociado, ni omitir aria-invalid al haber error.
Si una mutación propuesta rompe contrato (por ejemplo, derivar autocapitalize=‘none’ en un tipo email, o derivar inputmode=‘text’ cuando el type es numérico), la policy revierte al valor canónico y el sistema registra la razón en la telemetría agent-aware. La regla de oro del Input plástico: el contexto puede ajustar cómo se introduce el dato; no puede cambiar qué dato se espera.
Genealogía
Árbol de evolución
HTML estilizado
<input type='text'> con clase CSS y validación HTML5 nativa (required, pattern).
Consumidor Diseñador en Figma + desarrollador frontend
Componente React + esquema externo
Validación en cliente con Yup. Mensajes traducidos a tres idiomas. Primer Storybook.
Consumidor Equipo de producto, dieciocho productos
Input governable
Migración de Yup a Zod. Schema único compartido cliente y servidor. Auditoría WCAG completa.
Consumidor Veintinueve productos, primera adopción multi-equipo
Input.AI · expuesto vía MCP
Schema y mensajes accesibles vía MCP. OPA policy: agente tier-2 puede componer formularios pero no inventar tipos semánticos.
Consumidor Humano + agente tier-1 + agente tier-2
Input plástico
planificadoAdaptación de inputmode y teclado virtual al contexto del dispositivo y al idioma del lector.
Consumidor Estado 3 · cualquier cliente MCP
Notas del editor
Descartes catalogados
Variants rechazadas
variant='floating-label' Floating label de Material Design rompía el comportamiento de autocompletado en gestores de contraseñas y degradaba la lectura por SR. Sustituido por label estática arriba.
variant='inline-validation-keystroke' Validar en cada keystroke generaba ruido cognitivo y violaciones de SC 3.3.1. Restringido a validación on-blur y on-submit.
Referencias cruzadas
- Familia: Inputs / Form fields.
- Técnica relacionada: Nº 007 · RAG con chunking coherente.
- Estado al que pertenece: Estado 2 · Agéntico.