[COMPONENTE 11] Implementar Sidebar TOC con ScrollSpy custom - Issue #121
- CREAR: template-parts/content-toc.php
* Función PHP apu_generate_toc() para generar TOC automáticamente
* Regex para buscar H2 con atributo ID
* Solo se muestra en is_single()
- MODIFICAR: single.php (sidebar)
* Agregar div.sidebar-sticky wrapper
* Integrar get_template_part('template-parts/content', 'toc')
* Preparar espacio para CTA Box (componente 12)
- MODIFICAR: style.css (+87 líneas)
* 9 selectores CSS + 4 pseudo-elementos scrollbar
* Sticky positioning (top: 85px)
* Max-height calculado con calc()
* Scroll interno con overflow-y: auto
* Min-height: 0 (crítico para scroll en flexbox)
* Border-left indicator (navy, NO naranja)
* Scrollbar personalizado 6px (solo Webkit)
- MODIFICAR: main.js (+66 líneas)
* Función updateActiveSection() para ScrollSpy
* Algoritmo SIMPLE: verifica si pasaste el top
* Offset scroll: navbarHeight + 100
* Smooth scroll: navbarHeight + 40
* Selector .toc-container a (NO .toc-link)
* NO tiene auto-scroll del TOC
* NO actualiza URL con history.pushState()
Características:
✅ Generación automática desde H2 con ID
✅ ScrollSpy custom (JavaScript vanilla, NO Bootstrap)
✅ Sticky positioning con flexbox
✅ Scroll interno solo en lista
✅ Border-left indicator activo
✅ Scrollbar delgado personalizado
Selectores REALES usados:
- .toc-container a (NO .toc-link)
- .toc-container h4 (NO .toc-title)
- .toc-container li (NO .toc-list li)
🎨 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -918,3 +918,90 @@ img {
|
||||
.post-content a:hover {
|
||||
color: var(--color-orange-hover);
|
||||
}
|
||||
|
||||
/* === SIDEBAR TOC === */
|
||||
|
||||
.sidebar-sticky {
|
||||
position: sticky;
|
||||
top: 85px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.toc-container {
|
||||
margin-bottom: 13px;
|
||||
background: #ffffff;
|
||||
border: 1px solid var(--color-neutral-100);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
padding: 12px 16px;
|
||||
max-height: calc(100vh - 71px - 10px - 250px - 15px - 15px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.toc-container h4 {
|
||||
color: var(--color-navy-primary);
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid var(--color-neutral-100);
|
||||
margin-bottom: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
font-size: 1rem;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.toc-list {
|
||||
overflow-y: auto;
|
||||
padding-right: 0.5rem;
|
||||
list-style: none;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.toc-container li {
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
|
||||
.toc-container a {
|
||||
display: block;
|
||||
padding: 0.3rem 0.85rem;
|
||||
color: var(--color-neutral-600);
|
||||
text-decoration: none;
|
||||
border-left: 3px solid transparent;
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 4px;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.toc-container a:hover {
|
||||
background: var(--color-neutral-50);
|
||||
border-left-color: var(--color-navy-primary);
|
||||
color: var(--color-navy-primary);
|
||||
}
|
||||
|
||||
.toc-container a.active {
|
||||
background: var(--color-neutral-50);
|
||||
border-left-color: var(--color-navy-primary);
|
||||
color: var(--color-navy-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.toc-list::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.toc-list::-webkit-scrollbar-track {
|
||||
background: var(--color-neutral-50);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.toc-list::-webkit-scrollbar-thumb {
|
||||
background: var(--color-neutral-600);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.toc-list::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--color-neutral-700);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user