mirror of
https://github.com/litruv/Docs-Viewer.git
synced 2026-07-25 03:06:07 +10:00
Refactor header rendering and add clickable headers with highlight effect
This commit is contained in:
48
index.js
48
index.js
@@ -197,10 +197,9 @@ class DOMService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createFolderHeaderWithFile(iconClass, doc) {
|
createFolderHeaderWithFile(iconClass, doc) {
|
||||||
const iconStyle = doc.color ? `color: ${doc.color};` : '';
|
|
||||||
return `
|
return `
|
||||||
<div class="folder-icons">
|
<div class="folder-icons">
|
||||||
<i class="${iconClass} folder-icon" style="${iconStyle}"></i>
|
<i class="${iconClass} folder-icon"></i>
|
||||||
</div>
|
</div>
|
||||||
<span>${doc.title}</span>
|
<span>${doc.title}</span>
|
||||||
<a href="?${doc.slug}" class="folder-link" title="View folder page">
|
<a href="?${doc.slug}" class="folder-link" title="View folder page">
|
||||||
@@ -209,10 +208,9 @@ class DOMService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createFolderHeaderBasic(iconClass, doc) {
|
createFolderHeaderBasic(iconClass, doc) {
|
||||||
const iconStyle = doc.color ? `color: ${doc.color};` : '';
|
|
||||||
return `
|
return `
|
||||||
<div class="folder-icons">
|
<div class="folder-icons">
|
||||||
<i class="${iconClass} folder-icon" style="${iconStyle}"></i>
|
<i class="${iconClass} folder-icon"></i>
|
||||||
</div>
|
</div>
|
||||||
<span>${doc.title}</span>`;
|
<span>${doc.title}</span>`;
|
||||||
}
|
}
|
||||||
@@ -346,6 +344,20 @@ class DocumentService {
|
|||||||
}
|
}
|
||||||
return link.replace(/^<a /, `<a${attrs} `);
|
return link.replace(/^<a /, `<a${attrs} `);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add custom heading renderer to make headers clickable - without link icon
|
||||||
|
const originalHeading = renderer.heading.bind(renderer);
|
||||||
|
renderer.heading = (text, level) => {
|
||||||
|
const escapedText = text.toLowerCase()
|
||||||
|
.replace(/[^\w\s-]/g, '')
|
||||||
|
.replace(/\s+/g, '-');
|
||||||
|
|
||||||
|
const id = escapedText;
|
||||||
|
|
||||||
|
return `<h${level} id="${id}" class="clickable-header">
|
||||||
|
${text}
|
||||||
|
</h${level}>`;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCode(code, language) {
|
renderCode(code, language) {
|
||||||
@@ -541,17 +553,6 @@ class Documentation {
|
|||||||
this.indexData = data;
|
this.indexData = data;
|
||||||
window._indexData = data;
|
window._indexData = data;
|
||||||
|
|
||||||
// Load custom CSS files if specified
|
|
||||||
if (data.customCSS) {
|
|
||||||
const cssFiles = Array.isArray(data.customCSS) ? data.customCSS : [data.customCSS];
|
|
||||||
cssFiles.forEach(cssFile => {
|
|
||||||
const link = document.createElement('link');
|
|
||||||
link.rel = 'stylesheet';
|
|
||||||
link.href = cssFile;
|
|
||||||
document.head.appendChild(link);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.populateAuthorInfo(data.author);
|
this.populateAuthorInfo(data.author);
|
||||||
window.originalDocTitle = data.metadata.site_name || 'Documentation';
|
window.originalDocTitle = data.metadata.site_name || 'Documentation';
|
||||||
document.title = window.originalDocTitle;
|
document.title = window.originalDocTitle;
|
||||||
@@ -636,6 +637,23 @@ class Documentation {
|
|||||||
const headings = document.querySelectorAll('h2, h3, h4, h5, h6');
|
const headings = document.querySelectorAll('h2, h3, h4, h5, h6');
|
||||||
const headingLinks = this.domService.createOutline(headings);
|
const headingLinks = this.domService.createOutline(headings);
|
||||||
|
|
||||||
|
// Add click handlers to all headers
|
||||||
|
headings.forEach(heading => {
|
||||||
|
heading.addEventListener('click', (e) => {
|
||||||
|
// Don't trigger if clicking on fold toggle
|
||||||
|
if (e.target.closest('svg') || e.target.closest('.header-anchor')) return;
|
||||||
|
|
||||||
|
const id = heading.id;
|
||||||
|
if (id) {
|
||||||
|
history.pushState(null, '', `${window.location.pathname}${window.location.search}#${id}`);
|
||||||
|
this.domService.scrollToElement(heading);
|
||||||
|
heading.classList.remove('highlight');
|
||||||
|
void heading.offsetWidth;
|
||||||
|
heading.classList.add('highlight');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.setupScrollObserver(headings, headingLinks);
|
this.setupScrollObserver(headings, headingLinks);
|
||||||
|
|
||||||
window._currentPath = path;
|
window._currentPath = path;
|
||||||
|
|||||||
18
styles.css
18
styles.css
@@ -261,10 +261,9 @@ body {
|
|||||||
color: var(--ifm-color-content-secondary);
|
color: var(--ifm-color-content-secondary);
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
transition: color 0.2s;
|
transition: color 0.2s;
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.social-links a:hover {
|
social-links a:hover {
|
||||||
color: var(--ifm-color-primary);
|
color: var(--ifm-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,3 +567,18 @@ body {
|
|||||||
.github-link a:hover {
|
.github-link a:hover {
|
||||||
color: var(--ifm-color-primary);
|
color: var(--ifm-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clickable-header {
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.clickable-header:hover {
|
||||||
|
color: #3498db;
|
||||||
|
}
|
||||||
|
.clickable-header.highlight {
|
||||||
|
animation: highlight-fade 1.5s;
|
||||||
|
}
|
||||||
|
@keyframes highlight-fade {
|
||||||
|
0% { background-color: rgba(52, 152, 219, 0.2); }
|
||||||
|
100% { background-color: transparent; }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user