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.
svelte-kit-vice/docs/process/CONTINUE-nav-tree.md

99 lines
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 `open` es un getter
de soma (el expand-set) que alimenta `aria-expanded`/`data-state`; el toggle
dispara `emerge-expand`/`emerge-collapse` vía `runtime.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 un `emerge`
canónico (espeja collapsible/tree-view). scope = `['soma','sema','eidos']`.
- **Filas propias** (`<a>`/`<button>` estilizados por el recipe), NO `Link`/
`Button` compuestos — como anchor-nav; el contrato a11y es de nav-tree.
- **`isExpanded` es query PURA** (sin `$effect` que escriba estado): abierto si
no-colapsado-por-usuario Y (expandido-por-usuario O en-trail O `defaultOpen`).
- **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`
(`NavTreeProvider` raíz + `NavTreeItemProvider` por 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` (token `indent`),
`eidos/generated/base.css` (generado), `web/routes/uix/+layout@.svelte`
(pack `navTreeSema` registrado).
## 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-group
`data-ready`) de sesiones paralelas SIN commitear — NO son de nav-tree.
## Qué FALTA (orden para mañana)
1. **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; harness `SystemAxes`/`MotionPanel`/`SemaPanel`/
`DemoTrace`; `type Tab` en UNA línea con `// prettier-ignore`). Contenido
live: un árbol REAL de ~40 nodos y 3 niveles (p. ej. el mapa de `docs/`),
control de `activeHref` (select o los propios links moviéndolo), trail vivo.
El pack de sema YA está registrado en el layout.
2. **Entrada de nav**: añadir `nav-tree` a la lista de componentes en
`web/routes/uix/+layout@.svelte` (donde se añadió `anchor-nav`).
3. **Verificar en NAVEGADOR** (obligatorio, es UI): árbol renderiza; trail
auto-expandido al cambiar `activeHref`; chevron rota en `data-state=open`;
link activo toma color primary + peso; grupo colapsado = `hidden`;
`aria-current="page"` + `aria-expanded`/`aria-controls` correctos; DARK
(`colorScheme:'dark'` vía Playwright) y RTL. ⚠️ El Browser pane SUSPENDIDO
da `getComputedStyle` de color OBSOLETO (lección anchor-nav) — si el color
activo se ve mal, verifícalo en chromium foreground, NO es bug.
4. **Review adversarial** (workflow, como sticky/anchor-nav): dimensiones
correctness-scrollspy/trail · reactividad-lifecycle · morfo-a11y ·
css-recipe. Verificador escéptico por hallazgo. Arregla confirmados.
5. **Commit final + registro** en `PLAN-blocks.md` §7 (F1.8 HECHA) + memoria
`project_blocks_tier_2026-07-21.md` (F1 = 7/8) + `MEMORY.md`.
## Gotchas / lecciones de esta tanda
- **Correr `contracts.test.ts`**, no solo `npm run check` — destapa READMEs de
soma faltantes (le pasó a anchor-nav) y attrs/DOM-writes hardcodeados.
- `aria-expanded` necesita `stateRef` (da `'true'/'false'`); un `propRef`
booleano NO (el resolver solo convierte booleanos en aria para `stateRef`).
- 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 con `renderProps()`** (menubar).

Powered by TurnKey Linux.