feat(dashboard): improve mobile inventory UX and fix desktop viewport overflow
Mobile Inventory Improvements: - Add icon-based sub-tabs (user/box/building) with responsive labels - Desktop shows icon + label, mobile shows icon-only for compact layout - Add proper scroll containers for inventory content with flex layout - Increase touch drag delay from 150ms to 500ms to prevent accidental widget moves during scrolling Widget Content Fixes: - Add max-height constraint to .rpg-widget to prevent grid cell overflow - Add flex properties (flex: 1, min-height: 0, overflow: auto) to all widget content - Ensures content scrolls internally instead of expanding widget bounds - Fix .rpg-inventory-widget to use flex properties instead of height: 100% Layout Fixes: - Change characters widget default size from 2x3 to 2x2 for better viewport fit - Remove excess spacing from dashboard container (gap: 0.75rem) - Remove vertical padding from dashboard header - Eliminates desktop scrollbar caused by cumulative spacing All widgets now fit properly within viewport on both desktop and mobile.
This commit is contained in:
@@ -30,7 +30,7 @@ export class DragDropHandler {
|
|||||||
showCollisions: true,
|
showCollisions: true,
|
||||||
enableSnap: true,
|
enableSnap: true,
|
||||||
ghostOpacity: 0.5,
|
ghostOpacity: 0.5,
|
||||||
touchDelay: 150, // Delay before touch drag starts (ms)
|
touchDelay: 500, // Delay before touch drag starts (ms) - longer delay prevents accidental moves during scrolling
|
||||||
mouseMoveThreshold: 5, // Pixels mouse must move before drag starts
|
mouseMoveThreshold: 5, // Pixels mouse must move before drag starts
|
||||||
...options
|
...options
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -135,14 +135,17 @@ export function registerInventoryWidget(registry, dependencies) {
|
|||||||
function renderSubTabs(activeTab) {
|
function renderSubTabs(activeTab) {
|
||||||
return `
|
return `
|
||||||
<div class="rpg-inventory-subtabs">
|
<div class="rpg-inventory-subtabs">
|
||||||
<button class="rpg-inventory-subtab ${activeTab === 'onPerson' ? 'active' : ''}" data-tab="onPerson">
|
<button class="rpg-inventory-subtab ${activeTab === 'onPerson' ? 'active' : ''}" data-tab="onPerson" title="On Person">
|
||||||
On Person
|
<i class="fa-solid fa-user"></i>
|
||||||
|
<span class="rpg-subtab-label">On Person</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="rpg-inventory-subtab ${activeTab === 'stored' ? 'active' : ''}" data-tab="stored">
|
<button class="rpg-inventory-subtab ${activeTab === 'stored' ? 'active' : ''}" data-tab="stored" title="Stored">
|
||||||
Stored
|
<i class="fa-solid fa-box"></i>
|
||||||
|
<span class="rpg-subtab-label">Stored</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="rpg-inventory-subtab ${activeTab === 'assets' ? 'active' : ''}" data-tab="assets">
|
<button class="rpg-inventory-subtab ${activeTab === 'assets' ? 'active' : ''}" data-tab="assets" title="Assets">
|
||||||
Assets
|
<i class="fa-solid fa-building"></i>
|
||||||
|
<span class="rpg-subtab-label">Assets</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ export function registerPresentCharactersWidget(registry, dependencies) {
|
|||||||
description: 'Character cards with avatars, traits, and relationships',
|
description: 'Character cards with avatars, traits, and relationships',
|
||||||
category: 'scene',
|
category: 'scene',
|
||||||
minSize: { w: 2, h: 2 },
|
minSize: { w: 2, h: 2 },
|
||||||
defaultSize: { w: 2, h: 3 },
|
defaultSize: { w: 2, h: 2 }, // Compact size fits both mobile and desktop viewports
|
||||||
maxAutoSize: { w: 4, h: 5 }, // Max size for auto-arrange expansion (supports up to 4-col on large displays)
|
maxAutoSize: { w: 4, h: 5 }, // Max size for auto-arrange expansion (supports up to 4-col on large displays)
|
||||||
requiresSchema: false,
|
requiresSchema: false,
|
||||||
|
|
||||||
|
|||||||
@@ -1049,7 +1049,6 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
.rpg-dashboard-container {
|
.rpg-dashboard-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.75rem;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -1060,7 +1059,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.5rem 0;
|
padding: 0;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
@@ -1203,6 +1202,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
overflow: visible; /* Allow resize handles to extend beyond widget bounds */
|
overflow: visible; /* Allow resize handles to extend beyond widget bounds */
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
max-height: 100%; /* Prevent content from overflowing grid cell */
|
||||||
|
|
||||||
/* Unified widget styling - consistent look for all widgets */
|
/* Unified widget styling - consistent look for all widgets */
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
@@ -1215,6 +1215,9 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
.rpg-widget > * {
|
.rpg-widget > * {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rpg-widget .rpg-stats-content {
|
.rpg-widget .rpg-stats-content {
|
||||||
@@ -4793,6 +4796,23 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Inventory Widget - Flex container for proper scrolling */
|
||||||
|
.rpg-inventory-widget {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inventory Views - Scrollable content area */
|
||||||
|
.rpg-inventory-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;
|
||||||
@@ -4811,6 +4831,18 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inventory-subtab i {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-subtab-label {
|
||||||
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rpg-inventory-subtab:hover {
|
.rpg-inventory-subtab:hover {
|
||||||
@@ -5352,13 +5384,23 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
/* Mobile Responsive Styles */
|
/* Mobile Responsive Styles */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.rpg-inventory-subtabs {
|
.rpg-inventory-subtabs {
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
gap: 0.35rem;
|
gap: 0.5rem;
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rpg-inventory-subtab {
|
.rpg-inventory-subtab {
|
||||||
font-size: 1rem;
|
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
|
min-width: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inventory-subtab i {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide labels on mobile - icon only */
|
||||||
|
.rpg-subtab-label {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rpg-inventory-header {
|
.rpg-inventory-header {
|
||||||
|
|||||||
Reference in New Issue
Block a user