5.8 KiB
CONTINUE — F1.8 nav-tree (handoff 2026-07-22) · CERRADO
F1.8 HECHA (2026-07-22). Este handoff queda como registro de la tanda: demo, verificación en navegador real, review adversarial (10 hallazgos confirmados, todos arreglados) y cierre están completos. El registro definitivo vive en
docs/process/PLAN-blocks.md§7. Lo que sigue es el estado tal como quedó al PARAR aquella sesión (histórico).
Estado al parar: componente COMPLETO y en verde en todos los gates
estáticos; falta demo + verificación en navegador + review adversarial +
commit final + registro. Plan maestro: docs/process/PLAN-blocks.md §F1.8.
Qué es (decisiones ya tomadas y ratificadas en fase 0)
Árbol de navegación data-driven (E-1) para docs-shell: el app pasa
nodes (datos) + activeHref (su URL); el componente resuelve el nodo activo,
deriva el trail de ancestros y auto-expande el trail. APG Disclosure
Navigation (landmark <nav> + links nativos + botones disclosure), NO
tree-view (que es un WIDGET de selección role=tree).
Frontera vs tree-view: rol + interacción + modelo de datos distintos →
componente separado, no extensión. (Scope-approval cerrado.)
Decisiones de diseño (todas implementadas):
- Disclosure propio (no compone Collapsible): el estado
openes un getter de soma (el expand-set) que alimentaaria-expanded/data-state; el toggle disparaemerge-expand/emerge-collapsevíaruntime.trigger(sema +setExpanded). NO hay máquina de eventos que sostenga el estado. emerge+ pack de sema: corregido en fase 5 — el audit A-3.1 exige eventos en un componente interactivo; el toggle de disclosure ES unemergecanónico (espeja collapsible/tree-view). scope =['soma','sema','eidos'].- Filas propias (
<a>/<button>estilizados por el recipe), NOLink/Buttoncompuestos — como anchor-nav; el contrato a11y es de nav-tree. isExpandedes query PURA (sin$effectque escriba estado): abierto si no-colapsado-por-usuario Y (expandido-por-usuario O en-trail OdefaultOpen).- Profundidad = CSS var
--_nav-tree-depth(no attr por nivel). - Nodo padre navegable = link + chevron (patrón Fumadocs); sin href = botón.
Ficheros (todos escritos, type-clean)
- Morfo:
src/uix/morfo/components/nav-tree.ts(6 partes; eventos emerge;expression:'pack'). - Soma:
src/uix/soma/components/nav-tree/—nav-tree-provider.svelte.ts(NavTreeProviderraíz +NavTreeItemProviderpor nodo),types.ts,langs.ts,components/nav-tree.svelte(Provider),components/nav-tree-node.svelte(recursivo),exports.ts,index.ts,README.md. - Eidos:
src/uix/eidos/components/nav-tree/—nav-tree.svelte(forward),nav-tree.css(recipe),types.ts,index.ts,README.md. - Sema pack:
src/uix/sema/components/nav-tree.ts. - Langs:
src/uix/langs/components/nav-tree.ts. - Registros:
langs/components/index.ts,soma/components/index.ts,sema/components/index.ts,eidos/lib/recipes/base.ts(tokenindent),eidos/generated/base.css(generado),web/routes/uix/+layout@.svelte(packnavTreeSemaregistrado).
Gates que YA pasan
npx tsx scripts/component-audit.ts --only nav-tree→ PASS.npx tsx scripts/eidos-lint.ts nav-tree→ 20 morfo-backed, 0 invalid.npx svelte-check→ 0 errores en nav-tree + pack.npx vitest run src/uix/contracts.test.ts→ mis partes limpias. ⚠️ Quedan 2 fallos AJENOS (menubar-provider DOM-write · radio-groupdata-ready) de sesiones paralelas SIN commitear — NO son de nav-tree.
Qué FALTA (orden para mañana)
- Demo
web/routes/uix/components/nav-tree/+page.svelte— canónica, misma profundidad que anchor-nav (9 pestañas: live/system/motion/sema/services/ api/morfo/recipe/a11y; harnessSystemAxes/MotionPanel/SemaPanel/DemoTrace;type Taben UNA línea con// prettier-ignore). Contenido live: un árbol REAL de ~40 nodos y 3 niveles (p. ej. el mapa dedocs/), control deactiveHref(select o los propios links moviéndolo), trail vivo. El pack de sema YA está registrado en el layout. - Entrada de nav: añadir
nav-treea la lista de componentes enweb/routes/uix/+layout@.svelte(donde se añadióanchor-nav). - Verificar en NAVEGADOR (obligatorio, es UI): árbol renderiza; trail
auto-expandido al cambiar
activeHref; chevron rota endata-state=open; link activo toma color primary + peso; grupo colapsado =hidden;aria-current="page"+aria-expanded/aria-controlscorrectos; DARK (colorScheme:'dark'vía Playwright) y RTL. ⚠️ El Browser pane SUSPENDIDO dagetComputedStylede color OBSOLETO (lección anchor-nav) — si el color activo se ve mal, verifícalo en chromium foreground, NO es bug. - Review adversarial (workflow, como sticky/anchor-nav): dimensiones correctness-scrollspy/trail · reactividad-lifecycle · morfo-a11y · css-recipe. Verificador escéptico por hallazgo. Arregla confirmados.
- Commit final + registro en
PLAN-blocks.md§7 (F1.8 HECHA) + memoriaproject_blocks_tier_2026-07-21.md(F1 = 7/8) +MEMORY.md.
Gotchas / lecciones de esta tanda
- Correr
contracts.test.ts, no solonpm run check— destapa READMEs de soma faltantes (le pasó a anchor-nav) y attrs/DOM-writes hardcodeados. aria-expandednecesitastateRef(da'true'/'false'); unpropRefbooleano NO (el resolver solo convierte booleanos en aria parastateRef).- El estado de un part se puede alimentar con un getter (
states:{open:()=>…}) sin evento; los eventos emerge son para la sema (espeja collapsible). resolveProps(bindings)es puro pero NO incluye el marker/id; el patrón data-driven blessed es providers per-nodo conrenderProps()(menubar).