You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
15 KiB
15 KiB
button — ficha de auditoría de componente
- Fecha: 2026-07-07 · Auditoría: componentes (piloto 1 — calibra el formato)
- Método: solo análisis — los fixes se ejecutan tras auditar TODO el catálogo; esta ficha registra hallazgos + propuestas de solución (locales y las que escalan al sistema).
- Tier: control interactivo · Morfo scope:
['soma','sema','eidos']· Familia: acciones - Capas: morfo · soma · eidos · sema: sin pack (cascada por defecto)
- Máquina (
component:audit --only button): NEEDS-WORK —E-2.3(falta README a nivel eidos). R-rules (color/tipografía/recipe-contract): limpias. (Reglas D-* de demo excluidas — corrección de alcance 2026-07-07: la auditoría cubre solo las capas del componente.) - Vigencia re-auditoría: ficha piloto — YA a profundidad de referencia (todas las capas leídas con evidencia); este retrofit solo extrae las demos del alcance.
Tabla de dimensiones
| # | Dimensión | Estado | Evidencia / nota |
|---|---|---|---|
| 1 | Composición vs declaración | ✓ | API compositiva; child (asChild) ✓; Spinner morfo-declarado con razón documentada (derivado de estado, no composición) |
| 2 | Naming de props | ✓ con hallazgo | Props canónicas (disabled/loading/type/color/intent); ver S-1 (hooks CSS mixtos clase/data) |
| 3 | Coherencia semántica ecosistema/theming | ✓ ejemplar | intent = SOLO visual (cap. 22 §11 citado); contact sin intent; cascada intent-gana-sobre-color en provider; anti-patrón contact+fulfill documentado (cap. 22 §8) |
| 4 | API normalizada | ✓ | OptsFromProps; defaults documentados; color tipado laxo para paleta per THEMING §25.5 con re-type en eidos; onPress = feedback diagnóstico (no side-effect) |
| 5 | Tokens usados | ✓ | Piloto de la cascada --button-palette-*; recipe R-limpio; focus por --focus-ring-*; 0 usos de state-layer = correcto (todas las variantes son valenced — swap de paleta; sin tier neutro) |
| 6 | Parte semántica | validar | F-6: sin pack sema — contact.activate suena por el default de familia → ver S-3 |
| 7 | Animaciones | ✓ | Sin @keyframes perceptuales locales; press vía sistema (--press-*); spinner = periodo funcional |
| 8 | Contrato morfo | ✓ con hallazgo | Ejemplar: APG enlazado, keyboard declarado, textos localizados, data-state eliminado con la razón del clobbering (audit 05-27) documentada. F-1: Spinner con archetype: 'item' siendo parte display |
| 9 | Accesibilidad | ✓ | aria-busy en loading, aria-disabled, iconos aria-hidden, iconOnly conserva label sr-only, loadingText mantiene children sr-only, Enter/Space nativos, touch coarse por arquetipo trigger |
| 10 | Adopción theming | ✓ | Bundle de size vía recipe; depth n/a (no flota); focus modelo superficies (outline) ✓; palette cascade ✓ |
| 11 | Composición interna | ✓ | Participa en Field.Provider (disabled OR-merge); consume contexto ButtonGroup para defaults (prop explícita gana); es el COMPUESTO por IconButton/triggers |
| 12 | Estados y ciclo | ✓ | disabled/loading completos (click gated en ambos); type default 'button' (anti-submit implícito); controlled n/a (stateless) |
| 13 | Disciplina runtime | ✓ | Runtime-direct; sin DOM manual; sin timers; $derived limpios |
| 14 | fuera de alcance | Demos excluidas de la auditoría (corrección 2026-07-07) — sus reglas D-* viven en tmp/component-audit.md, no aquí | |
| 15 | Docs + tests | gap doble | F-4: falta README eidos (el de soma completo con ## Sema events ✓) · F-7: CERO tests de provider/wrapper · F-2: doc de aria-label en soma types referencia iconOnly (prop de eidos — fuga de capa) · F-3: docblock del wrapper cita data-state que el morfo eliminó |
| 16 | i18n | ✓ | texts del morfo localizados (#?components.button.*); loadingText del consumidor; sin strings hardcoded |
Hallazgos y propuestas de solución — del componente
| ID | Hallazgo | Propuesta de solución |
|---|---|---|
| F-1 | Spinner declara archetype: 'item' siendo parte display (aria-hidden, no interactiva) — el gotcha conocido: item arrastra estilo interactivo |
Quitar el archetype de la parte Spinner (omitirlo, como manda la doctrina para partes display); verificación visual antes/después del spinner en los 3 placements |
| F-2 | En soma types.ts, el doc de aria-label dice "Required when iconOnly is true" — iconOnly es prop de EIDOS, no existe en soma (fuga de capa en docs) |
Reescribir el JSDoc sin referencia cross-capa ("override del nombre accesible; obligatorio cuando el botón no tiene texto visible") |
| F-3 | Docblock de eidos button.svelte dice "Soma owns … data-state" — button eliminó data-state (el propio morfo documenta por qué) |
Actualizar el docblock (data-loading/data-disabled por presencia; sin data-state) |
| F-4 | Falta eidos/components/button/README.md (convención que la máquina exige, E-2.3); el README de soma está completo |
Crear el README eidos siguiendo el patrón de los existentes (css-field/number-field): API visual, variantes, tokens públicos del recipe, composición |
| (retirado — hallazgo de demo, fuera del alcance de la auditoría) | — | |
| F-6 | Sin pack sema propio: contact.activate materializa el default de la familia |
Ver S-3 (es cuestión doctrinal de catálogo, no de button) |
| F-7 | Cero tests de provider/wrapper — el componente insignia sin suite | Suite browser del provider (click→contact-activate, gate disabled/loading, Field-merge, cascada intent/color, snippetProps) + wrapper (spinner placements, iconOnly sr-only, loadingText swap). Alcance/momento: ver S-2 |
Hallazgos que escalan al sistema / theming
| ID | Hallazgo (visto en button, alcance = catálogo) | Propuesta |
|---|---|---|
| S-1 | Hooks estructurales del wrapper como clases (.eidos-button-{body,icon,sr-only,loading-text}, 6 selectores) conviviendo con data-attrs ([data-button-icon]). Las clases escapan a eidos-lint (solo valida [data-*]) y crean segunda gramática de hooks |
Norma de catálogo: hooks de selector SIEMPRE data-attrs (data-{c}-{kebab}), nunca clases; clase permitida solo como utility sin selector en CSS (p. ej. contenedor neutro). + Guard: lint que detecte \.eidos- / clases con estilos en CSS de componentes. Aplicar en el fix-phase a todos los que salgan en el barrido |
| S-2 | Ausencia de tests no es exclusiva de button — política de alcance pendiente | Decisión de catálogo (checkpoint post-barrido): (a) suite por componente durante fase de fixes, o (b) batch de testing como fase propia posterior. La ficha de cada componente registra su cobertura actual para dimensionar |
| S-3 | Componentes de contacto genérico sin pack sema: ¿el default de familia ES la firma, o el catálogo quiere carácter per-componente en los buques insignia? | Decisión doctrinal (checkpoint): criterio de cuándo un componente MERECE pack (hoy: 38 packs, sesgo a fields/pickers). Propuesta: default-de-familia = firma legítima para contact genérico (button, link); pack solo donde el patrón añade significado (ya es el statu quo — canonizarlo por escrito en CANON/sema doctrine) |
| S-4 | El README vive en DOS niveles (soma completo aquí; la máquina exige el de eidos) — heterogeneidad de dónde vive la doc del componente | Norma: definir el nivel canónico (propuesta: eidos = puerta del consumidor, con API visual + tokens; soma README = contrato headless). La máquina ya empuja a eidos (E-2.3) — ratificar y documentar en component-guide |
Veredictos
(pendiente — checkpoint único post-barrido; las propuestas de arriba se ejecutan en la fase de fixes)