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
- Renderizado condicional: Solo pinta el aside si hay acciones O si hay suficientes headings (
headings.length >= minHeadings) - Sección de acciones: Stack vertical de botones, siempre visible
- Sección de TOC: Listado h2/h3 con anidación visual (h3 con padding-left extra)
- 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
- 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-h3para anidación
Toggle interno (solo si hay headings)
- Botón tipo
action-button-block aria-expandedsincronizado con estado colapsado- Atributos
data-collapseden 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]]