- style.css: Full CSS theme with frosted glass cards, sidebar styling, dashboard individual glass cards, search overlay, FA icon replacements - sidebar.js: Collapsible sidebar toggle with Unraid logo, search popup (moved to body to escape backdrop-filter containing block), Cmd+K shortcut Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
144 lines
4.5 KiB
JavaScript
144 lines
4.5 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
var KEY = 'unraid-sidebar-expanded';
|
|
|
|
// Restore state immediately (before DOM ready to avoid flash)
|
|
if (localStorage.getItem(KEY) === '1') {
|
|
document.documentElement.classList.add('sidebar-expanded');
|
|
}
|
|
|
|
function init() {
|
|
var menu = document.getElementById('menu');
|
|
if (!menu) return;
|
|
|
|
// --- Unraid logo (absolute positioned at very top of sidebar) ---
|
|
if (!document.getElementById('sidebar-logo')) {
|
|
var logo = document.createElement('img');
|
|
logo.id = 'sidebar-logo';
|
|
logo.src = 'https://cdn.jsdelivr.net/gh/selfhst/icons@main/svg/unraid.svg';
|
|
logo.alt = '';
|
|
menu.appendChild(logo);
|
|
}
|
|
|
|
// --- Toggle button with chevron (below logo) ---
|
|
if (!document.getElementById('sidebar-toggle-btn')) {
|
|
var btn = document.createElement('button');
|
|
btn.id = 'sidebar-toggle-btn';
|
|
btn.type = 'button';
|
|
btn.title = 'Toggle Sidebar';
|
|
btn.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>';
|
|
|
|
btn.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
var expanded = document.documentElement.classList.toggle('sidebar-expanded');
|
|
localStorage.setItem(KEY, expanded ? '1' : '0');
|
|
});
|
|
|
|
menu.appendChild(btn);
|
|
}
|
|
|
|
// --- Search overlay (delayed to wait for search plugin init) ---
|
|
setTimeout(initSearchOverlay, 800);
|
|
}
|
|
|
|
function initSearchOverlay() {
|
|
if (!window.jQuery) return;
|
|
|
|
var searchItem = document.querySelector('.nav-item.gui_search');
|
|
if (!searchItem) return;
|
|
|
|
// Remove default hover-based open/close handlers
|
|
$(searchItem).off('mouseenter mouseleave');
|
|
|
|
var link = searchItem.querySelector('a');
|
|
if (!link) return;
|
|
|
|
// Replace hover with click
|
|
link.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
toggleSearch();
|
|
});
|
|
|
|
// Add Cmd+K / Ctrl+K keyboard shortcut (sidebar theme doesn't have one by default)
|
|
document.addEventListener('keydown', function(e) {
|
|
var isMac = navigator.platform.indexOf('Mac') > -1;
|
|
if ((isMac ? e.metaKey : e.ctrlKey) && (e.key === 'k' || e.keyCode === 75)) {
|
|
if ($('[role="modal"]:visible').length) return;
|
|
e.preventDefault();
|
|
toggleSearch();
|
|
}
|
|
});
|
|
}
|
|
|
|
function toggleSearch() {
|
|
var existing = document.getElementById('guiSearchBoxSpan');
|
|
if (existing) {
|
|
closeSearch();
|
|
return;
|
|
}
|
|
|
|
// Call original gui_search to create the input
|
|
if (typeof gui_search === 'function') {
|
|
gui_search();
|
|
}
|
|
|
|
// Move search box to <body> — backdrop-filter on #menu creates a new
|
|
// containing block, so position:fixed inside it is relative to #menu
|
|
// and gets clipped by overflow:hidden. Moving to body fixes this.
|
|
var searchSpan = document.getElementById('guiSearchBoxSpan');
|
|
if (searchSpan) {
|
|
document.body.appendChild(searchSpan);
|
|
}
|
|
|
|
// Create backdrop overlay
|
|
if (!document.getElementById('search-backdrop')) {
|
|
var backdrop = document.createElement('div');
|
|
backdrop.id = 'search-backdrop';
|
|
backdrop.addEventListener('click', function() {
|
|
closeSearch();
|
|
});
|
|
document.body.appendChild(backdrop);
|
|
}
|
|
|
|
// Override blur/keydown behavior on the input
|
|
var input = document.getElementById('guiSearchBox');
|
|
if (input && window.jQuery) {
|
|
$(input).off('blur keydown');
|
|
|
|
input.addEventListener('blur', function() {
|
|
setTimeout(function() {
|
|
var span = document.getElementById('guiSearchBoxSpan');
|
|
if (span && !span.contains(document.activeElement)) {
|
|
closeSearch();
|
|
}
|
|
}, 300);
|
|
});
|
|
|
|
input.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape' || e.keyCode === 27) {
|
|
e.preventDefault();
|
|
closeSearch();
|
|
}
|
|
});
|
|
|
|
input.focus();
|
|
}
|
|
}
|
|
|
|
function closeSearch() {
|
|
// Remove the search span directly (works whether moved to body or not)
|
|
var span = document.getElementById('guiSearchBoxSpan');
|
|
if (span) span.remove();
|
|
var backdrop = document.getElementById('search-backdrop');
|
|
if (backdrop) backdrop.remove();
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|