fix: improve inventory and quests widget resizing at narrow widths
Resolved issues where inventory and quests widgets didn't properly adapt to narrow desktop widths (~296px, 2 columns): - Assets tab was cut off (1/3 off-screen) - Widgets shrank vertically instead of expanding - Sub-tabs overflowed horizontally Changes: 1. Widget onResize Handlers (inventoryWidget.js, questsWidget.js): - Strengthened inventory onResize to call render() for full re-layout - Added quests onResize handler with re-render + width-aware styling - Both apply responsive CSS classes at narrow widths 2. Increased maxAutoSize for 2-Column Layouts: - inventoryWidget.js: h: 6 → h: 8 (creates expansion headroom) - questsWidget.js: h: 5 → h: 7 (user requested height) - Previously: defaultSize = maxAutoSize → zero expansion possible - Now: defaultSize < maxAutoSize → widgets can expand vertically 3. Added Missing Quests Widget Container Styles (style.css): - Added .rpg-quests-widget and .rpg-quests-views flex container styles - Proper overflow handling (hidden on container, auto on content) - Prevents Assets tab horizontal cut-off 4. Implemented Compact Mode CSS (style.css): - .rpg-inventory-compact: reduced padding, icon-only sub-tabs - Applied when widget width < 6 grid units - Prevents 3 sub-tabs from overflowing 296px container - Icons remain visible, labels hidden for space savings 5. Grid Engine Boolean Return (gridEngine.js): - setContainerWidth now returns true/false for column changes - Allows DashboardManager to optimize resize handling Why This Works: - Auto-layout expansion requires defaultSize < maxAutoSize for headroom - Flex container styles prevent overflow with proper scroll handling - Compact mode makes sub-tabs fit within narrow containers - onResize handlers ensure internal layouts adapt to dimension changes Fixes: Assets tab cut-off, vertical shrinking, sub-tab overflow at ~296px
This commit is contained in:
@@ -119,6 +119,7 @@ export class GridEngine {
|
|||||||
* Recalculates column count based on new width and notifies if changed.
|
* Recalculates column count based on new width and notifies if changed.
|
||||||
*
|
*
|
||||||
* @param {number} width - Container width in pixels
|
* @param {number} width - Container width in pixels
|
||||||
|
* @returns {boolean} True if column count changed, false otherwise
|
||||||
*/
|
*/
|
||||||
setContainerWidth(width) {
|
setContainerWidth(width) {
|
||||||
const oldColumns = this.columns;
|
const oldColumns = this.columns;
|
||||||
@@ -131,7 +132,10 @@ export class GridEngine {
|
|||||||
if (oldColumns !== this.columns && this.onColumnsChange) {
|
if (oldColumns !== this.columns && this.onColumnsChange) {
|
||||||
console.log('[GridEngine] Column count changed from', oldColumns, 'to', this.columns);
|
console.log('[GridEngine] Column count changed from', oldColumns, 'to', this.columns);
|
||||||
this.onColumnsChange(this.columns, oldColumns);
|
this.onColumnsChange(this.columns, oldColumns);
|
||||||
|
return true; // Signal that columns changed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false; // Columns did NOT change
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -65,8 +65,19 @@ export function registerInventoryWidget(registry, dependencies) {
|
|||||||
description: 'Full inventory system with On Person, Stored, and Assets',
|
description: 'Full inventory system with On Person, Stored, and Assets',
|
||||||
category: 'inventory',
|
category: 'inventory',
|
||||||
minSize: { w: 2, h: 4 },
|
minSize: { w: 2, h: 4 },
|
||||||
defaultSize: { w: 2, h: 6 },
|
// Column-aware sizing: compact on mobile, spacious on desktop
|
||||||
maxAutoSize: { w: 3, h: 8 }, // Max size for auto-arrange expansion (full tab)
|
defaultSize: (columns) => {
|
||||||
|
if (columns <= 2) {
|
||||||
|
return { w: 2, h: 5 }; // Mobile: 2×5 (full width, compact)
|
||||||
|
}
|
||||||
|
return { w: 2, h: 6 }; // Desktop: 2×6 (default)
|
||||||
|
},
|
||||||
|
maxAutoSize: (columns) => {
|
||||||
|
if (columns <= 2) {
|
||||||
|
return { w: 2, h: 8 }; // Mobile: 2×8 max (increased for expansion headroom)
|
||||||
|
}
|
||||||
|
return { w: 3, h: 8 }; // Desktop: 3×8 max (can expand)
|
||||||
|
},
|
||||||
requiresSchema: false,
|
requiresSchema: false,
|
||||||
|
|
||||||
render(container, config = {}) {
|
render(container, config = {}) {
|
||||||
@@ -113,14 +124,18 @@ export function registerInventoryWidget(registry, dependencies) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onResize(container, newW, newH) {
|
onResize(container, newW, newH) {
|
||||||
// Adjust layout for narrow widgets
|
// Re-render widget to update internal layout for new dimensions
|
||||||
const widget = container.querySelector('.rpg-inventory-widget');
|
// This ensures sub-tabs, item lists, and storage locations adapt correctly
|
||||||
if (!widget) return;
|
this.render(container, this.config || {});
|
||||||
|
|
||||||
if (newW < 6) {
|
// Apply compact mode styling if needed
|
||||||
widget.classList.add('rpg-inventory-compact');
|
const widget = container.querySelector('.rpg-inventory-widget');
|
||||||
} else {
|
if (widget) {
|
||||||
widget.classList.remove('rpg-inventory-compact');
|
if (newW < 6) {
|
||||||
|
widget.classList.add('rpg-inventory-compact');
|
||||||
|
} else {
|
||||||
|
widget.classList.remove('rpg-inventory-compact');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -395,8 +395,19 @@ export function registerQuestsWidget(registry, dependencies) {
|
|||||||
description: 'Quest tracking with main and optional quests',
|
description: 'Quest tracking with main and optional quests',
|
||||||
category: 'quests',
|
category: 'quests',
|
||||||
minSize: { w: 2, h: 4 },
|
minSize: { w: 2, h: 4 },
|
||||||
defaultSize: { w: 2, h: 5 },
|
// Column-aware sizing: compact on mobile, spacious on desktop
|
||||||
maxAutoSize: { w: 3, h: 7 },
|
defaultSize: (columns) => {
|
||||||
|
if (columns <= 2) {
|
||||||
|
return { w: 2, h: 4 }; // Mobile: 2×4 (full width, compact)
|
||||||
|
}
|
||||||
|
return { w: 2, h: 5 }; // Desktop: 2×5 (default)
|
||||||
|
},
|
||||||
|
maxAutoSize: (columns) => {
|
||||||
|
if (columns <= 2) {
|
||||||
|
return { w: 2, h: 7 }; // Mobile: 2×7 max (increased for expansion headroom)
|
||||||
|
}
|
||||||
|
return { w: 3, h: 7 }; // Desktop: 3×7 max (can expand)
|
||||||
|
},
|
||||||
requiresSchema: false,
|
requiresSchema: false,
|
||||||
|
|
||||||
render(container, config = {}) {
|
render(container, config = {}) {
|
||||||
@@ -436,6 +447,24 @@ export function registerQuestsWidget(registry, dependencies) {
|
|||||||
// Called when widget data changes externally
|
// Called when widget data changes externally
|
||||||
onDataUpdate(container, config = {}) {
|
onDataUpdate(container, config = {}) {
|
||||||
this.render(container, config);
|
this.render(container, config);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Called when widget is resized
|
||||||
|
onResize(container, newW, newH) {
|
||||||
|
// Re-render widget to update layout for new dimensions
|
||||||
|
this.render(container, this.config || {});
|
||||||
|
|
||||||
|
// Apply width-aware styling
|
||||||
|
const widget = container.querySelector('.rpg-quests-widget');
|
||||||
|
if (widget) {
|
||||||
|
if (newW >= 3) {
|
||||||
|
// Wide layout: constrain title width
|
||||||
|
widget.classList.add('rpg-quests-wide');
|
||||||
|
} else {
|
||||||
|
// Narrow layout: allow title to flex
|
||||||
|
widget.classList.remove('rpg-quests-wide');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6950,6 +6950,23 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Quests Widget - Flex container for proper scrolling */
|
||||||
|
.rpg-quests-widget {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Quests Views - Scrollable content area */
|
||||||
|
.rpg-quests-views {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
/* Sub-tabs Navigation */
|
/* Sub-tabs Navigation */
|
||||||
.rpg-inventory-subtabs {
|
.rpg-inventory-subtabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -7648,6 +7665,25 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Inventory Compact Mode (narrow widths, < 6 grid units) */
|
||||||
|
.rpg-inventory-compact .rpg-inventory-subtabs {
|
||||||
|
gap: 0.25rem; /* Reduced from 0.5rem */
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inventory-compact .rpg-inventory-subtab {
|
||||||
|
padding: 0.4rem 0.6rem; /* Reduced from 0.5rem 1rem */
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide labels on very narrow widths, show icons only */
|
||||||
|
.rpg-inventory-compact .rpg-subtab-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inventory-compact .rpg-inventory-subtab i {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
QUESTS SYSTEM STYLING
|
QUESTS SYSTEM STYLING
|
||||||
============================================ */
|
============================================ */
|
||||||
@@ -7907,6 +7943,19 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Quest widget header constraints for wide layouts */
|
||||||
|
.rpg-quests-wide .rpg-quest-section-title {
|
||||||
|
max-width: 200px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-quests-wide .rpg-quest-header {
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mobile Responsive Styles */
|
/* Mobile Responsive Styles */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.rpg-quests-subtabs {
|
.rpg-quests-subtabs {
|
||||||
|
|||||||
Reference in New Issue
Block a user