CreaRack-SL

Componente PageToc — Panel TOC flotante compartido

Entidadactivecreado Tue Jul 21#src#ui#components#documentation#ux#astro

Panel lateral fijo (desktop >1400px) que centraliza la tabla de contenidos (TOC) flotante y botones de acción para documentos. Sustituye código duplicado en wiki, visor de informes y reports del Supercontexto.

Propósito

Unificar el TOC flotante que existía triplicado en tres visores de documentos. Antes cada uno tenía su propia implementación de:

  • Extracción y listado de headings (h2/h3)
  • Botones de acción (“Editar”, “Ver raw”, “Vista limpia”)
  • Colapsabilidad con estado en localStorage
  • Estilos de panel vidrio (backdrop-filter)

Ahora: una única fuente de verdad que reutilizan los tres.

Interfaz

export interface TocAction {
  label: string;           // Texto del botón
  href: string;            // URL destino
  title?: string;          // Tooltip
  external?: boolean;      // Abre en pestaña nueva
}

export interface TocHeading {
  depth: number;           // 2 o 3 (h2, h3)
  text: string;            // Texto del encabezado
  slug: string;            // ID para ancla (#slug)
}

interface Props {
  headings?: TocHeading[];  // Listado de h2/h3 con IDs (generado por renderMarkdownDoc)
  actions?: TocAction[];    // Botones de acción
  minHeadings?: number;     // Umbral para mostrar TOC (defecto: 3)
}

Comportamiento

  1. Renderizado condicional: Solo pinta el aside si hay acciones O si hay suficientes headings (headings.length >= minHeadings)
  2. Sección de acciones: Stack vertical de botones, siempre visible
  3. Sección de TOC: Listado h2/h3 con anidación visual (h3 con padding-left extra)
  4. Colapsabilidad:
    • Toggle “Mostrar/Ocultar índice” en la sección de acciones
    • Estado persistido en localStorage[wikiTocCollapsed] (valor '0' ó '1')
    • Aplicado al cargar + reactivo al click
    • Efecto: se oculta .page-toc-body, el panel encoge a solo botones
  5. Responsive: @media (max-width: 1400px) { display: none; }

Sub-componentes

Sección .page-toc-actions

  • Flex column, gap 6px
  • Separator inferior (border-bottom) si hay acciones + TOC
  • Botones heredan .action-button + .action-button-block (estilos base en cada página)

Sección .page-toc-body (solo si showToc && headings.length >= minHeadings)

  • Título “En esta página” (uppercase, muted, 0.7rem)
  • <ul> con items para cada heading
  • Clases toc-h2 / toc-h3 para anidación

Toggle interno (solo si hay headings)

  • Botón tipo action-button-block
  • aria-expanded sincronizado con estado colapsado
  • Atributos data-collapsed en el aside para selector CSS

Uso

---
import PageToc from '../../components/PageToc.astro';
import { renderMarkdownDoc } from '../../lib/markdownDoc';

const { title, html, headings } = renderMarkdownDoc(rawMarkdown);
---

<DocsLayout>
  <Fragment set:html={html} />
  
  <PageToc
    headings={headings}
    actions={[
      { label: 'Editar', href: editUrl, title: 'Editar este artículo' },
      { label: 'Ver raw', href: rawUrl, external: true },
    ]}
  />
</DocsLayout>

Ubicaciones en uso

  • Wiki: /pages/wiki/[...slug].astro — acciones “Vista limpia” + “Editar”
  • Informes: /pages/informes/ver/[slug].astro — acción “Ver raw”
  • Reports Supercontexto: /pages/supercontext/reports/[slug].astro — acción “Ver raw”

Véase también

  • [[entity—src—function—render-markdown-doc]]
  • [[entity—src—page—wiki-page]]
  • [[entity—src—page—informe-viewer]]
  • [[entity—src—page—reports-viewer]]