added search bar

This commit is contained in:
2026-03-19 09:02:27 +01:00
parent 2a63f44c59
commit 6d413f81b6
6 changed files with 235 additions and 70 deletions

View File

@@ -14,9 +14,87 @@
{% if not no_navigation %}
<nav>
<a href="{% if is_static %}index.html{% else %}.{% endif %}">Home</a>
<div class="search-container" style="position: relative; margin-left: auto; display: flex; align-items: center;">
<input type="text" id="wiki-search" placeholder="Search wiki..." autocomplete="off">
<div id="search-results">
</div>
</div>
</nav>
{% endif %}
<div id="content">{% block content %}{% endblock content %}</div>
</body>
{% if is_static %}
<script src="search-index.js"></script>
{% endif %}
<script>
async function getSearchIndex() {
if (window.WIKI_SEARCH_INDEX) {
console.log("Using pre-loaded search index");
return window.WIKI_SEARCH_INDEX;
}
try {
const response = await fetch('search-index.json');
if (!response.ok) throw new Error("Search index not found");
return await response.json();
} catch (e) {
console.error("Failed to load search index:", e);
return [];
}
}
(function() {
let searchIndex = null;
const searchInput = document.getElementById('wiki-search');
const resultsDiv = document.getElementById('search-results');
async function initSearch() {
if (searchIndex) return;
try {
searchIndex = await getSearchIndex();
} catch (e) {
console.error("Failed to load search index:", e);
}
}
searchInput.addEventListener('focus', initSearch);
searchInput.addEventListener('input', (e) => {
const query = e.target.value.toLowerCase().trim();
if (!query || !searchIndex) {
resultsDiv.style.display = 'none';
return;
}
const matches = searchIndex.filter(page =>
page.title.toLowerCase().includes(query) ||
(page.category && page.category.toLowerCase().includes(query))
).slice(0, 10);
if (matches.length > 0) {
resultsDiv.innerHTML = matches.map(page => `
<a href="${page.url}" class="search-result">
<div class="search-result-title">${page.title}</div>
<div class="search-result-category">${page.category || 'General'}</div>
</a>
`).join('');
resultsDiv.style.display = 'block';
} else {
resultsDiv.innerHTML = '<div style="padding: 10px; color: #838ba7;">No results found</div>';
resultsDiv.style.display = 'block';
}
});
// Close results when clicking outside
document.addEventListener('click', (e) => {
if (!searchInput.contains(e.target) && !resultsDiv.contains(e.target)) {
resultsDiv.style.display = 'none';
}
});
})();
</script>
</html>

View File

@@ -38,6 +38,56 @@ body {
padding: 0 20px 35px;
}
#wiki-search {
background: #232634;
border: 1px solid #414559;
color: #c6d0f5;
padding: 5px 10px;
border-radius: 4px;
outline: none;
}
#wiki-search:focus {
border-color: #8caaee;
}
#search-results {
display: none;
position: absolute;
top: 100%;
right: 0;
background: var(--container-bg);
border: 1px solid var(--border-color);
width: 300px;
z-index: 1000;
border-radius: 4px;
margin-top: 5px;
overflow: hidden;
}
#search-results a:hover {
background: var(--lighter-bg);
}
/* FIX: */
/* #search-results a:hover .search-result-category { */
/* text-decoration: none; */
/* } */
.search-result {
display: block;
padding: 10px;
text-decoration: none;
color: var(--text-main);
border-bottom: 1px solid var(--border-color);
transition: background 0.2s;
}
.search-result-category {
color: var(--text-muted);
font-size: 0.8rem;
}
.wiki-header {
border-bottom: 2px solid;
border-image-source: linear-gradient(to right, var(--accent), transparent);