Volver a la wiki

Componente PageToc — Panel TOC flotante compartido

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:

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

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

Toggle interno (solo si hay headings)

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

Véase también

Subir