mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2026-04-14 13:19:09 +02:00
docs: improve docs page
This commit is contained in:
parent
5ff362e1ea
commit
98b2cb93e2
1 changed files with 743 additions and 539 deletions
|
|
@ -212,6 +212,117 @@ I also add this javascript to add header pinning functionality to the site, usin
|
|||
const body = document.body;
|
||||
|
||||
if (!content || !pinnedList || !toggleBtn || !clearAllBtn || !toc) return;
|
||||
function injectSearch() {
|
||||
// Check if already injected
|
||||
if (document.getElementById('toc-search-input')) return;
|
||||
|
||||
const searchContainer = document.createElement('div');
|
||||
searchContainer.id = 'toc-search-container';
|
||||
|
||||
const searchInput = document.createElement('input');
|
||||
searchInput.id = 'toc-search-input';
|
||||
searchInput.type = 'text';
|
||||
searchInput.placeholder = 'Search TOC...';
|
||||
searchInput.autocomplete = 'off';
|
||||
|
||||
const clearBtn = document.createElement('button');
|
||||
clearBtn.id = 'toc-search-clear';
|
||||
clearBtn.type = 'button';
|
||||
clearBtn.textContent = 'Clear';
|
||||
|
||||
searchContainer.appendChild(searchInput);
|
||||
searchContainer.appendChild(clearBtn);
|
||||
|
||||
toc.insertBefore(searchContainer, toc.firstChild);
|
||||
|
||||
function filterTOC(term) {
|
||||
const allLinks = toc.querySelectorAll('a');
|
||||
|
||||
allLinks.forEach(link => {
|
||||
const li = link.closest('li');
|
||||
if (!li) return;
|
||||
|
||||
const text = link.textContent.toLowerCase();
|
||||
const matches = text.includes(term);
|
||||
|
||||
if (matches) {
|
||||
li.classList.remove('hidden-by-search');
|
||||
let parent = li.parentElement;
|
||||
while (parent && parent !== toc) {
|
||||
if (parent.tagName === 'UL') {
|
||||
parent.style.display = '';
|
||||
}
|
||||
if (parent.tagName === 'LI') {
|
||||
parent.classList.remove('hidden-by-search');
|
||||
}
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
} else {
|
||||
li.classList.add('hidden-by-search');
|
||||
}
|
||||
});
|
||||
|
||||
if (term === '') {
|
||||
const allLis = toc.querySelectorAll('li');
|
||||
allLis.forEach(li => li.classList.remove('hidden-by-search'));
|
||||
}
|
||||
}
|
||||
|
||||
searchInput.addEventListener('input', function(e) {
|
||||
const term = e.target.value.toLowerCase();
|
||||
filterTOC(term);
|
||||
});
|
||||
|
||||
clearBtn.addEventListener('click', function() {
|
||||
searchInput.value = '';
|
||||
filterTOC('');
|
||||
searchInput.focus();
|
||||
});
|
||||
}
|
||||
injectSearch();
|
||||
function addHeadingLinks() {
|
||||
const headers = content.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||
headers.forEach(header => {
|
||||
const id = header.getAttribute('id');
|
||||
if (!id) return;
|
||||
|
||||
if (header.querySelector('.heading-link')) return;
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.className = 'heading-link';
|
||||
link.href = '#' + id;
|
||||
link.textContent = '#';
|
||||
link.title = 'Copy link to this heading';
|
||||
|
||||
const pinBtn = header.querySelector('.toc-pin-btn');
|
||||
if (pinBtn) {
|
||||
header.insertBefore(link, pinBtn);
|
||||
} else {
|
||||
header.appendChild(link);
|
||||
}
|
||||
|
||||
link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
const url = window.location.origin + window.location.pathname + '#' + id;
|
||||
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(url).then(() => {
|
||||
const originalText = link.textContent;
|
||||
link.textContent = '✓';
|
||||
setTimeout(() => {
|
||||
link.textContent = originalText;
|
||||
}, 1000);
|
||||
}).catch(err => {
|
||||
console.warn('Failed to copy to clipboard', err);
|
||||
window.location.hash = id;
|
||||
});
|
||||
} else {
|
||||
window.location.hash = id;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
addHeadingLinks();
|
||||
|
||||
let mobileTocBtn = document.getElementById('mobile-toc-toggle');
|
||||
if (!mobileTocBtn) {
|
||||
|
|
@ -241,6 +352,31 @@ I also add this javascript to add header pinning functionality to the site, usin
|
|||
else body.classList.remove('mobile-panel-open');
|
||||
}
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
if (window.innerWidth > 1000) return;
|
||||
|
||||
if (!anyMobilePanelOpen()) return;
|
||||
|
||||
const clickedInsideToc = toc.contains(e.target);
|
||||
const clickedInsidePinned = pinnedPanel.contains(e.target);
|
||||
const clickedTocBtn = mobileTocBtn.contains(e.target);
|
||||
const clickedPinnedBtn = mobilePinnedBtn.contains(e.target);
|
||||
|
||||
const clickedInteractive =
|
||||
e.target.tagName === 'A' ||
|
||||
e.target.tagName === 'BUTTON' ||
|
||||
e.target.tagName === 'INPUT' ||
|
||||
e.target.tagName === 'TEXTAREA' ||
|
||||
e.target.closest('a') ||
|
||||
e.target.closest('button');
|
||||
|
||||
if (!clickedInsideToc && !clickedInsidePinned && !clickedTocBtn && !clickedPinnedBtn && !clickedInteractive) {
|
||||
toc.classList.remove('mobile-visible');
|
||||
pinnedPanel.classList.remove('mobile-visible');
|
||||
updateBodyMobilePanelState();
|
||||
}
|
||||
});
|
||||
|
||||
mobileTocBtn.addEventListener('click', function() {
|
||||
const isOpen = toc.classList.toggle('mobile-visible');
|
||||
if (isOpen) {
|
||||
|
|
@ -511,7 +647,7 @@ I also add this javascript to add header pinning functionality to the site, usin
|
|||
showBtn = document.createElement('button');
|
||||
showBtn.id = 'show-pinned-btn';
|
||||
showBtn.type = 'button';
|
||||
showBtn.textContent = 'Show Pinned';
|
||||
showBtn.textContent = 'Pinned';
|
||||
document.body.appendChild(showBtn);
|
||||
}
|
||||
|
||||
|
|
@ -725,7 +861,7 @@ I also add this javascript to add header pinning functionality to the site, usin
|
|||
attachPinBehavior(pinBtn, href, text);
|
||||
});
|
||||
|
||||
const headers = content.querySelectorAll('h2, h3, h4, h5');
|
||||
const headers = content.querySelectorAll('h2, h3, h4, h5, h6');
|
||||
headers.forEach(header => {
|
||||
const id = header.getAttribute('id');
|
||||
if (!id) return;
|
||||
|
|
@ -32296,12 +32432,67 @@ This is the stylesheet used by the [[#h:12880c64-229c-4063-9eea-387a97490676][HT
|
|||
background-color: #232b32;
|
||||
border-right: 1px solid #2f3b45;
|
||||
font-size: 0.9rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#table-of-contents h2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#toc-search-container {
|
||||
margin-bottom: 1rem;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: #232b32;
|
||||
z-index: 10;
|
||||
padding-bottom: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
#toc-search-input {
|
||||
flex: 1;
|
||||
padding: 0.5rem;
|
||||
background-color: #1d252c;
|
||||
border: 1px solid #2f3b45;
|
||||
color: #b7c5d3;
|
||||
border-radius: 4px;
|
||||
font-size: 0.9rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#toc-search-input:focus {
|
||||
outline: none;
|
||||
border-color: #5ec4ff;
|
||||
}
|
||||
|
||||
#toc-search-clear {
|
||||
padding: 0.5rem 0.7rem;
|
||||
background-color: #2f3b45;
|
||||
border: 1px solid #3a4a56;
|
||||
color: #b7c5d3;
|
||||
cursor: pointer;
|
||||
font-size: 0.85rem;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#toc-search-clear:hover {
|
||||
background-color: #3a4a56;
|
||||
color: #ff6b6b;
|
||||
}
|
||||
|
||||
.hidden-by-search {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#text-table-of-contents {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#text-table-of-contents ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
|
|
@ -32353,29 +32544,12 @@ This is the stylesheet used by the [[#h:12880c64-229c-4063-9eea-387a97490676][HT
|
|||
margin-top: 2.2rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.0rem;
|
||||
}
|
||||
h1 { font-size: 2rem; }
|
||||
h2 { font-size: 1.6rem; }
|
||||
h3 { font-size: 1.3rem; }
|
||||
h4 { font-size: 1.2rem; }
|
||||
h5 { font-size: 1.1rem; }
|
||||
h6 { font-size: 1.0rem; }
|
||||
|
||||
a {
|
||||
color: #5ec4ff;
|
||||
|
|
@ -32677,6 +32851,36 @@ This is the stylesheet used by the [[#h:12880c64-229c-4063-9eea-387a97490676][HT
|
|||
max-width: 100%;
|
||||
padding: 1.5rem 1.25rem;
|
||||
}
|
||||
#toc-search-container {
|
||||
top: 3rem;
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.heading-link {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.2s, visibility 0.2s;
|
||||
margin-left: 0.5rem;
|
||||
color: #718ca1;
|
||||
text-decoration: none;
|
||||
font-size: 0.8em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.heading-link:hover {
|
||||
color: #5ec4ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1:hover .heading-link,
|
||||
h2:hover .heading-link,
|
||||
h3:hover .heading-link,
|
||||
h4:hover .heading-link,
|
||||
h5:hover .heading-link,
|
||||
h6:hover .heading-link {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue