mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 07:05:43 -03:00
feat: Implement auto-hide functionality for sidebar and update controls layout
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
.folder-sidebar {
|
.folder-sidebar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 68px; /* Below header */
|
top: 68px; /* Below header */
|
||||||
left: 0px;
|
left: 10px;
|
||||||
width: 230px;
|
width: 230px;
|
||||||
height: calc(100vh - 88px);
|
height: calc(100vh - 88px);
|
||||||
background: var(--bg-color);
|
background: var(--bg-color);
|
||||||
@@ -17,12 +17,41 @@
|
|||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Auto-hide states */
|
||||||
|
.folder-sidebar.auto-hide {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-sidebar.auto-hide.hover-active {
|
||||||
|
transform: translateX(0);
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
.folder-sidebar.collapsed {
|
.folder-sidebar.collapsed {
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hover detection area for auto-hide */
|
||||||
|
.sidebar-hover-area {
|
||||||
|
position: fixed;
|
||||||
|
top: 68px;
|
||||||
|
left: 0;
|
||||||
|
width: 20px;
|
||||||
|
height: calc(100vh - 88px);
|
||||||
|
z-index: calc(var(--z-overlay) - 1);
|
||||||
|
background: transparent;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-hover-area.disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-header {
|
.sidebar-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -54,9 +83,17 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
flex: 1;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-toggle-close {
|
.sidebar-header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-action-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
@@ -72,12 +109,23 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-toggle-close:hover {
|
.sidebar-action-btn:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
background: var(--lora-surface);
|
background: var(--lora-surface);
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-action-btn.active {
|
||||||
|
opacity: 1;
|
||||||
|
background: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.15);
|
||||||
|
color: var(--lora-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove old close button styles */
|
||||||
|
.sidebar-toggle-close {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-content {
|
.sidebar-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -328,38 +376,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidebar Toggle Button */
|
|
||||||
.sidebar-toggle-container {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-toggle-btn {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--card-bg);
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
color: var(--text-color);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-toggle-btn:hover {
|
|
||||||
background: var(--lora-accent);
|
|
||||||
color: white;
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-toggle-btn.active {
|
|
||||||
background: var(--lora-accent);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Empty State */
|
/* Empty State */
|
||||||
.sidebar-tree-placeholder {
|
.sidebar-tree-placeholder {
|
||||||
padding: 24px 16px;
|
padding: 24px 16px;
|
||||||
|
|||||||
@@ -224,33 +224,6 @@
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidebar Toggle Button */
|
|
||||||
.sidebar-toggle-container {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-toggle-btn {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--card-bg);
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
color: var(--text-color);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-toggle-btn:hover {
|
|
||||||
background: var(--lora-accent);
|
|
||||||
color: white;
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Icon-only button style */
|
/* Icon-only button style */
|
||||||
.icon-only {
|
.icon-only {
|
||||||
min-width: unset !important;
|
min-width: unset !important;
|
||||||
@@ -298,7 +271,6 @@
|
|||||||
/* Prevent text selection in control and header areas */
|
/* Prevent text selection in control and header areas */
|
||||||
.control-group button,
|
.control-group button,
|
||||||
.control-group select,
|
.control-group select,
|
||||||
.sidebar-toggle-btn,
|
|
||||||
.bulk-operations-panel,
|
.bulk-operations-panel,
|
||||||
.app-header,
|
.app-header,
|
||||||
.header-branding,
|
.header-branding,
|
||||||
@@ -306,8 +278,7 @@
|
|||||||
.main-nav,
|
.main-nav,
|
||||||
.nav-item,
|
.nav-item,
|
||||||
.header-actions button,
|
.header-actions button,
|
||||||
.header-controls,
|
.header-controls {
|
||||||
.sidebar-toggle-container button {
|
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
@@ -391,14 +362,6 @@
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-toggle-container {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-toggle-btn:hover {
|
|
||||||
transform: none; /* Disable hover effects on mobile */
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-group button:hover {
|
.control-group button:hover {
|
||||||
transform: none; /* Disable hover effects on mobile */
|
transform: none; /* Disable hover effects on mobile */
|
||||||
|
|||||||
@@ -12,15 +12,23 @@ export class SidebarManager {
|
|||||||
this.selectedPath = '';
|
this.selectedPath = '';
|
||||||
this.expandedNodes = new Set();
|
this.expandedNodes = new Set();
|
||||||
this.isVisible = true;
|
this.isVisible = true;
|
||||||
|
this.isPinned = false;
|
||||||
this.apiClient = null;
|
this.apiClient = null;
|
||||||
this.openDropdown = null;
|
this.openDropdown = null;
|
||||||
|
this.hoverTimeout = null;
|
||||||
|
this.isHovering = false;
|
||||||
|
|
||||||
// Bind methods
|
// Bind methods
|
||||||
this.handleTreeClick = this.handleTreeClick.bind(this);
|
this.handleTreeClick = this.handleTreeClick.bind(this);
|
||||||
this.handleBreadcrumbClick = this.handleBreadcrumbClick.bind(this);
|
this.handleBreadcrumbClick = this.handleBreadcrumbClick.bind(this);
|
||||||
this.toggleSidebar = this.toggleSidebar.bind(this);
|
|
||||||
this.closeSidebar = this.closeSidebar.bind(this);
|
|
||||||
this.handleDocumentClick = this.handleDocumentClick.bind(this);
|
this.handleDocumentClick = this.handleDocumentClick.bind(this);
|
||||||
|
this.handleSidebarHeaderClick = this.handleSidebarHeaderClick.bind(this);
|
||||||
|
this.handlePinToggle = this.handlePinToggle.bind(this);
|
||||||
|
this.handleCollapseAll = this.handleCollapseAll.bind(this);
|
||||||
|
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
||||||
|
this.handleMouseLeave = this.handleMouseLeave.bind(this);
|
||||||
|
this.handleHoverAreaEnter = this.handleHoverAreaEnter.bind(this);
|
||||||
|
this.handleHoverAreaLeave = this.handleHoverAreaLeave.bind(this);
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@@ -32,6 +40,7 @@ export class SidebarManager {
|
|||||||
this.restoreSidebarState();
|
this.restoreSidebarState();
|
||||||
await this.loadFolderTree();
|
await this.loadFolderTree();
|
||||||
this.restoreSelectedFolder();
|
this.restoreSelectedFolder();
|
||||||
|
this.updateAutoHideState();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSidebarTitle() {
|
updateSidebarTitle() {
|
||||||
@@ -42,22 +51,22 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupEventHandlers() {
|
setupEventHandlers() {
|
||||||
// Sidebar toggle button
|
// Sidebar header (root selection) - only trigger on title area
|
||||||
const toggleBtn = document.querySelector('.sidebar-toggle-btn');
|
|
||||||
if (toggleBtn) {
|
|
||||||
toggleBtn.addEventListener('click', this.toggleSidebar);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sidebar header (root selection)
|
|
||||||
const sidebarHeader = document.getElementById('sidebarHeader');
|
const sidebarHeader = document.getElementById('sidebarHeader');
|
||||||
if (sidebarHeader) {
|
if (sidebarHeader) {
|
||||||
sidebarHeader.addEventListener('click', () => this.selectFolder(''));
|
sidebarHeader.addEventListener('click', this.handleSidebarHeaderClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sidebar close button
|
// Pin toggle button
|
||||||
const closeBtn = document.getElementById('sidebarToggleClose');
|
const pinToggleBtn = document.getElementById('sidebarPinToggle');
|
||||||
if (closeBtn) {
|
if (pinToggleBtn) {
|
||||||
closeBtn.addEventListener('click', this.closeSidebar);
|
pinToggleBtn.addEventListener('click', this.handlePinToggle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collapse all button
|
||||||
|
const collapseAllBtn = document.getElementById('sidebarCollapseAll');
|
||||||
|
if (collapseAllBtn) {
|
||||||
|
collapseAllBtn.addEventListener('click', this.handleCollapseAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tree click handler
|
// Tree click handler
|
||||||
@@ -72,27 +81,34 @@ export class SidebarManager {
|
|||||||
sidebarBreadcrumbNav.addEventListener('click', this.handleBreadcrumbClick);
|
sidebarBreadcrumbNav.addEventListener('click', this.handleBreadcrumbClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hover detection for auto-hide
|
||||||
|
const sidebar = document.getElementById('folderSidebar');
|
||||||
|
const hoverArea = document.getElementById('sidebarHoverArea');
|
||||||
|
|
||||||
|
if (sidebar) {
|
||||||
|
sidebar.addEventListener('mouseenter', this.handleMouseEnter);
|
||||||
|
sidebar.addEventListener('mouseleave', this.handleMouseLeave);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hoverArea) {
|
||||||
|
hoverArea.addEventListener('mouseenter', this.handleHoverAreaEnter);
|
||||||
|
hoverArea.addEventListener('mouseleave', this.handleHoverAreaLeave);
|
||||||
|
}
|
||||||
|
|
||||||
// Close sidebar when clicking outside on mobile
|
// Close sidebar when clicking outside on mobile
|
||||||
document.addEventListener('click', (e) => {
|
document.addEventListener('click', (e) => {
|
||||||
if (window.innerWidth <= 1024 && this.isVisible) {
|
if (window.innerWidth <= 1024 && this.isVisible) {
|
||||||
const sidebar = document.getElementById('folderSidebar');
|
const sidebar = document.getElementById('folderSidebar');
|
||||||
const toggleBtn = document.querySelector('.sidebar-toggle-btn');
|
|
||||||
|
|
||||||
if (sidebar && !sidebar.contains(e.target) &&
|
if (sidebar && !sidebar.contains(e.target)) {
|
||||||
toggleBtn && !toggleBtn.contains(e.target)) {
|
this.hideSidebar();
|
||||||
this.closeSidebar();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle window resize
|
// Handle window resize
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
if (window.innerWidth > 1024 && this.isVisible) {
|
this.updateAutoHideState();
|
||||||
const sidebar = document.getElementById('folderSidebar');
|
|
||||||
if (sidebar) {
|
|
||||||
sidebar.classList.remove('collapsed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add document click handler for closing dropdowns
|
// Add document click handler for closing dropdowns
|
||||||
@@ -106,10 +122,115 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closeDropdown() {
|
handleSidebarHeaderClick(event) {
|
||||||
if (this.openDropdown) {
|
// Only trigger root selection if clicking on the title area, not the buttons
|
||||||
this.openDropdown.classList.remove('open');
|
if (!event.target.closest('.sidebar-header-actions')) {
|
||||||
this.openDropdown = null;
|
this.selectFolder('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePinToggle(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.isPinned = !this.isPinned;
|
||||||
|
this.updateAutoHideState();
|
||||||
|
this.updatePinButton();
|
||||||
|
this.saveSidebarState();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCollapseAll(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.expandedNodes.clear();
|
||||||
|
this.renderTree();
|
||||||
|
this.saveExpandedState();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseEnter() {
|
||||||
|
this.isHovering = true;
|
||||||
|
if (this.hoverTimeout) {
|
||||||
|
clearTimeout(this.hoverTimeout);
|
||||||
|
this.hoverTimeout = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isPinned) {
|
||||||
|
this.showSidebar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseLeave() {
|
||||||
|
this.isHovering = false;
|
||||||
|
if (!this.isPinned) {
|
||||||
|
this.hoverTimeout = setTimeout(() => {
|
||||||
|
if (!this.isHovering) {
|
||||||
|
this.hideSidebar();
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleHoverAreaEnter() {
|
||||||
|
if (!this.isPinned) {
|
||||||
|
this.showSidebar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleHoverAreaLeave() {
|
||||||
|
// Let the sidebar's mouse leave handler deal with hiding
|
||||||
|
}
|
||||||
|
|
||||||
|
showSidebar() {
|
||||||
|
const sidebar = document.getElementById('folderSidebar');
|
||||||
|
if (sidebar && !this.isPinned) {
|
||||||
|
sidebar.classList.add('hover-active');
|
||||||
|
this.isVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideSidebar() {
|
||||||
|
const sidebar = document.getElementById('folderSidebar');
|
||||||
|
if (sidebar && !this.isPinned) {
|
||||||
|
sidebar.classList.remove('hover-active');
|
||||||
|
this.isVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAutoHideState() {
|
||||||
|
const sidebar = document.getElementById('folderSidebar');
|
||||||
|
const hoverArea = document.getElementById('sidebarHoverArea');
|
||||||
|
|
||||||
|
if (!sidebar || !hoverArea) return;
|
||||||
|
|
||||||
|
if (window.innerWidth <= 1024) {
|
||||||
|
// Mobile: always use collapsed state
|
||||||
|
sidebar.classList.remove('auto-hide', 'hover-active');
|
||||||
|
sidebar.classList.add('collapsed');
|
||||||
|
hoverArea.classList.add('disabled');
|
||||||
|
this.isVisible = false;
|
||||||
|
} else if (this.isPinned) {
|
||||||
|
// Desktop pinned: always visible
|
||||||
|
sidebar.classList.remove('auto-hide', 'collapsed', 'hover-active');
|
||||||
|
hoverArea.classList.add('disabled');
|
||||||
|
this.isVisible = true;
|
||||||
|
} else {
|
||||||
|
// Desktop auto-hide: use hover detection
|
||||||
|
sidebar.classList.remove('collapsed');
|
||||||
|
sidebar.classList.add('auto-hide');
|
||||||
|
hoverArea.classList.remove('disabled');
|
||||||
|
|
||||||
|
if (this.isHovering) {
|
||||||
|
sidebar.classList.add('hover-active');
|
||||||
|
this.isVisible = true;
|
||||||
|
} else {
|
||||||
|
sidebar.classList.remove('hover-active');
|
||||||
|
this.isVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePinButton() {
|
||||||
|
const pinBtn = document.getElementById('sidebarPinToggle');
|
||||||
|
if (pinBtn) {
|
||||||
|
pinBtn.classList.toggle('active', this.isPinned);
|
||||||
|
pinBtn.title = this.isPinned ? 'Unpin Sidebar' : 'Pin Sidebar';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,15 +376,12 @@ export class SidebarManager {
|
|||||||
this.pageControls.pageState.activeFolder = path || null;
|
this.pageControls.pageState.activeFolder = path || null;
|
||||||
setStorageItem(`${this.pageType}_activeFolder`, path || null);
|
setStorageItem(`${this.pageType}_activeFolder`, path || null);
|
||||||
|
|
||||||
// Always show breadcrumb container
|
|
||||||
// Removed hiding breadcrumb container code
|
|
||||||
|
|
||||||
// Reload models with new filter
|
// Reload models with new filter
|
||||||
await this.pageControls.resetAndReload();
|
await this.pageControls.resetAndReload();
|
||||||
|
|
||||||
// Auto-close sidebar on mobile after selection
|
// Auto-hide sidebar on mobile after selection
|
||||||
if (window.innerWidth <= 1024) {
|
if (window.innerWidth <= 1024) {
|
||||||
this.closeSidebar();
|
this.hideSidebar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,22 +605,13 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
restoreSidebarState() {
|
restoreSidebarState() {
|
||||||
const isVisible = getStorageItem(`${this.pageType}_sidebarVisible`, true);
|
const isPinned = getStorageItem(`${this.pageType}_sidebarPinned`, false);
|
||||||
const expandedPaths = getStorageItem(`${this.pageType}_expandedNodes`, []);
|
const expandedPaths = getStorageItem(`${this.pageType}_expandedNodes`, []);
|
||||||
|
|
||||||
this.isVisible = isVisible;
|
this.isPinned = isPinned;
|
||||||
this.expandedNodes = new Set(expandedPaths);
|
this.expandedNodes = new Set(expandedPaths);
|
||||||
|
|
||||||
const sidebar = document.getElementById('folderSidebar');
|
this.updatePinButton();
|
||||||
const toggleBtn = document.querySelector('.sidebar-toggle-btn');
|
|
||||||
|
|
||||||
if (sidebar) {
|
|
||||||
sidebar.classList.toggle('collapsed', !this.isVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toggleBtn) {
|
|
||||||
toggleBtn.classList.toggle('active', this.isVisible);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restoreSelectedFolder() {
|
restoreSelectedFolder() {
|
||||||
@@ -520,7 +629,7 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
saveSidebarState() {
|
saveSidebarState() {
|
||||||
setStorageItem(`${this.pageType}_sidebarVisible`, this.isVisible);
|
setStorageItem(`${this.pageType}_sidebarPinned`, this.isPinned);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveExpandedState() {
|
saveExpandedState() {
|
||||||
@@ -533,18 +642,25 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
// Clear any pending timeouts
|
||||||
|
if (this.hoverTimeout) {
|
||||||
|
clearTimeout(this.hoverTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up event handlers
|
// Clean up event handlers
|
||||||
const toggleBtn = document.querySelector('.sidebar-toggle-btn');
|
const pinToggleBtn = document.getElementById('sidebarPinToggle');
|
||||||
const closeBtn = document.getElementById('sidebarToggleClose');
|
const collapseAllBtn = document.getElementById('sidebarCollapseAll');
|
||||||
const folderTree = document.getElementById('sidebarFolderTree');
|
const folderTree = document.getElementById('sidebarFolderTree');
|
||||||
const sidebarBreadcrumbNav = document.getElementById('sidebarBreadcrumbNav');
|
const sidebarBreadcrumbNav = document.getElementById('sidebarBreadcrumbNav');
|
||||||
const sidebarHeader = document.getElementById('sidebarHeader');
|
const sidebarHeader = document.getElementById('sidebarHeader');
|
||||||
|
const sidebar = document.getElementById('folderSidebar');
|
||||||
|
const hoverArea = document.getElementById('sidebarHoverArea');
|
||||||
|
|
||||||
if (toggleBtn) {
|
if (pinToggleBtn) {
|
||||||
toggleBtn.removeEventListener('click', this.toggleSidebar);
|
pinToggleBtn.removeEventListener('click', this.handlePinToggle);
|
||||||
}
|
}
|
||||||
if (closeBtn) {
|
if (collapseAllBtn) {
|
||||||
closeBtn.removeEventListener('click', this.closeSidebar);
|
collapseAllBtn.removeEventListener('click', this.handleCollapseAll);
|
||||||
}
|
}
|
||||||
if (folderTree) {
|
if (folderTree) {
|
||||||
folderTree.removeEventListener('click', this.handleTreeClick);
|
folderTree.removeEventListener('click', this.handleTreeClick);
|
||||||
@@ -553,7 +669,15 @@ export class SidebarManager {
|
|||||||
sidebarBreadcrumbNav.removeEventListener('click', this.handleBreadcrumbClick);
|
sidebarBreadcrumbNav.removeEventListener('click', this.handleBreadcrumbClick);
|
||||||
}
|
}
|
||||||
if (sidebarHeader) {
|
if (sidebarHeader) {
|
||||||
sidebarHeader.removeEventListener('click', () => this.selectFolder(''));
|
sidebarHeader.removeEventListener('click', this.handleSidebarHeaderClick);
|
||||||
|
}
|
||||||
|
if (sidebar) {
|
||||||
|
sidebar.removeEventListener('mouseenter', this.handleMouseEnter);
|
||||||
|
sidebar.removeEventListener('mouseleave', this.handleMouseLeave);
|
||||||
|
}
|
||||||
|
if (hoverArea) {
|
||||||
|
hoverArea.removeEventListener('mouseenter', this.handleHoverAreaEnter);
|
||||||
|
hoverArea.removeEventListener('mouseleave', this.handleHoverAreaLeave);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove document click handler
|
// Remove document click handler
|
||||||
|
|||||||
@@ -65,12 +65,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="controls-right">
|
<div class="controls-right">
|
||||||
<div class="sidebar-toggle-container">
|
|
||||||
<button class="sidebar-toggle-btn icon-only" title="Toggle folder sidebar">
|
|
||||||
<i class="fas fa-folder-tree"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="keyboard-nav-hint tooltip">
|
<div class="keyboard-nav-hint tooltip">
|
||||||
<i class="fas fa-keyboard"></i>
|
<i class="fas fa-keyboard"></i>
|
||||||
<span class="tooltiptext">
|
<span class="tooltiptext">
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
|
<!-- Hover detection area -->
|
||||||
|
<div class="sidebar-hover-area" id="sidebarHoverArea"></div>
|
||||||
|
|
||||||
<!-- Folder Navigation Sidebar -->
|
<!-- Folder Navigation Sidebar -->
|
||||||
<div class="folder-sidebar" id="folderSidebar">
|
<div class="folder-sidebar" id="folderSidebar">
|
||||||
<div class="sidebar-header" id="sidebarHeader">
|
<div class="sidebar-header" id="sidebarHeader">
|
||||||
<h3><i class="fas fa-home"></i> <span id="sidebarTitle">Model Root</span></h3>
|
<h3><i class="fas fa-home"></i> <span id="sidebarTitle">Model Root</span></h3>
|
||||||
<button class="sidebar-toggle-close" id="sidebarToggleClose">
|
<div class="sidebar-header-actions">
|
||||||
<i class="fas fa-times"></i>
|
<button class="sidebar-action-btn" id="sidebarCollapseAll" title="Collapse All Folders">
|
||||||
</button>
|
<i class="fas fa-compress-alt"></i>
|
||||||
|
</button>
|
||||||
|
<button class="sidebar-action-btn" id="sidebarPinToggle" title="Pin/Unpin Sidebar">
|
||||||
|
<i class="fas fa-thumbtack"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-content">
|
<div class="sidebar-content">
|
||||||
<div class="sidebar-tree-container">
|
<div class="sidebar-tree-container">
|
||||||
|
|||||||
Reference in New Issue
Block a user