feat(dashboard): implement responsive header with tab scrolling and overflow menus
Add comprehensive responsive header system with Google-quality UX: Tab Navigation: - Add TabScrollManager for horizontal scrolling tabs - Left/Right navigation arrows appear when scrollable - Edge fade indicators show more content exists - Smooth scroll behavior with momentum - Progressive sizing: full → icon+name → icon-only - Automatic scroll position tracking Button Overflow System: - Add HeaderOverflowManager with ResizeObserver - Three responsive modes based on container width: * Full mode (>900px): all buttons visible * Overflow mode (500-900px): priority + "More" (⋮) menu * Compact mode (<500px): priority + hamburger (☰) menu - Priority buttons (Lock + Edit) always visible - Smooth transitions between modes Dropdown Menu: - Professional slide-down animation - Full keyboard navigation (arrows, Home, End, Escape) - Click-outside-to-close behavior - ARIA attributes for accessibility - Focus management and trap - Auto-refresh on edit mode changes - High z-index (10003) ensures visibility above all UI Cross-Tab Widget Dragging: - Add collision detection for widget placement - Implement moveWidgetToTab() with collision avoidance - Find available positions in target tab automatically - Update dragDrop.js to detect tab hover - Visual feedback with tab highlight on hover - Proper widget positioning after cross-tab move Additional Features: - Sort Tab button for current-tab-only auto-layout - Mobile optimizations with compact buttons - Responsive breakpoints at 768px and 480px - Hardware-accelerated animations - Touch-friendly 44px minimum targets Files changed: - New: tabScrollManager.js, headerOverflowManager.js - Modified: dashboardTemplate.html, dashboardIntegration.js - Modified: dashboardManager.js, dragDrop.js, style.css - Modified: editModeManager.js (lock state default)
This commit is contained in:
@@ -12,6 +12,8 @@ import { renderExtensionTemplateAsync } from '../../../../../../extensions.js';
|
||||
import { DashboardManager } from './dashboardManager.js';
|
||||
import { WidgetRegistry } from './widgetRegistry.js';
|
||||
import { generateDefaultDashboard } from './defaultLayout.js';
|
||||
import { TabScrollManager } from './tabScrollManager.js';
|
||||
import { HeaderOverflowManager } from './headerOverflowManager.js';
|
||||
|
||||
// Widget imports
|
||||
import { registerUserInfoWidget } from './widgets/userInfoWidget.js';
|
||||
@@ -24,6 +26,8 @@ import { registerInventoryWidget } from './widgets/inventoryWidget.js';
|
||||
|
||||
// Global dashboard manager instance
|
||||
let dashboardManager = null;
|
||||
let tabScrollManager = null;
|
||||
let headerOverflowManager = null;
|
||||
|
||||
/**
|
||||
* Get the dashboard manager instance
|
||||
@@ -101,6 +105,20 @@ export async function initializeDashboard(dependencies) {
|
||||
// Set up dashboard event listeners
|
||||
setupDashboardEventListeners(dependencies);
|
||||
|
||||
// Initialize tab scroll manager
|
||||
const tabsContainer = document.querySelector('#rpg-dashboard-tabs');
|
||||
if (tabsContainer) {
|
||||
tabScrollManager = new TabScrollManager(tabsContainer);
|
||||
tabScrollManager.init();
|
||||
}
|
||||
|
||||
// Initialize header overflow manager
|
||||
const headerRight = document.querySelector('#rpg-dashboard-header-right');
|
||||
if (headerRight) {
|
||||
headerOverflowManager = new HeaderOverflowManager(headerRight);
|
||||
headerOverflowManager.init();
|
||||
}
|
||||
|
||||
console.log('[RPG Companion] Dashboard v2 initialized successfully');
|
||||
return dashboardManager;
|
||||
|
||||
@@ -227,6 +245,17 @@ function setupDashboardEventListeners(dependencies) {
|
||||
});
|
||||
}
|
||||
|
||||
// Sort Tab button (layout current tab only)
|
||||
const sortTabBtn = document.querySelector('#rpg-dashboard-sort-tab');
|
||||
if (sortTabBtn) {
|
||||
sortTabBtn.addEventListener('click', () => {
|
||||
if (dashboardManager) {
|
||||
console.log('[RPG Companion] Sort tab button clicked');
|
||||
dashboardManager.autoLayoutCurrentTab();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Edit mode toggle
|
||||
const editModeBtn = document.querySelector('#rpg-dashboard-edit-mode');
|
||||
if (editModeBtn) {
|
||||
@@ -234,6 +263,10 @@ function setupDashboardEventListeners(dependencies) {
|
||||
if (dashboardManager && dashboardManager.editManager) {
|
||||
console.log('[RPG Companion] Edit button clicked');
|
||||
dashboardManager.editManager.toggleEditMode();
|
||||
// Refresh header overflow menu to reflect edit mode button visibility changes
|
||||
if (headerOverflowManager) {
|
||||
setTimeout(() => headerOverflowManager.refresh(), 50);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -256,6 +289,10 @@ function setupDashboardEventListeners(dependencies) {
|
||||
if (dashboardManager && dashboardManager.editManager) {
|
||||
console.log('[RPG Companion] Done button clicked');
|
||||
dashboardManager.editManager.exitEditMode(true); // Save changes
|
||||
// Refresh header overflow menu to reflect edit mode button visibility changes
|
||||
if (headerOverflowManager) {
|
||||
setTimeout(() => headerOverflowManager.refresh(), 50);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user