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:
Lucas 'Paperboy' Rose-Winters
2025-10-27 10:18:07 +11:00
parent 04bb52ed71
commit 45c5853dcb
4 changed files with 58 additions and 13 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ export class DragDropHandler {
showCollisions: true,
enableSnap: true,
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
...options
};
@@ -135,14 +135,17 @@ export function registerInventoryWidget(registry, dependencies) {
function renderSubTabs(activeTab) {
return `
<div class="rpg-inventory-subtabs">
<button class="rpg-inventory-subtab ${activeTab === 'onPerson' ? 'active' : ''}" data-tab="onPerson">
On Person
<button class="rpg-inventory-subtab ${activeTab === 'onPerson' ? 'active' : ''}" data-tab="onPerson" title="On Person">
<i class="fa-solid fa-user"></i>
<span class="rpg-subtab-label">On Person</span>
</button>
<button class="rpg-inventory-subtab ${activeTab === 'stored' ? 'active' : ''}" data-tab="stored">
Stored
<button class="rpg-inventory-subtab ${activeTab === 'stored' ? 'active' : ''}" data-tab="stored" title="Stored">
<i class="fa-solid fa-box"></i>
<span class="rpg-subtab-label">Stored</span>
</button>
<button class="rpg-inventory-subtab ${activeTab === 'assets' ? 'active' : ''}" data-tab="assets">
Assets
<button class="rpg-inventory-subtab ${activeTab === 'assets' ? 'active' : ''}" data-tab="assets" title="Assets">
<i class="fa-solid fa-building"></i>
<span class="rpg-subtab-label">Assets</span>
</button>
</div>
`;
@@ -237,7 +237,7 @@ export function registerPresentCharactersWidget(registry, dependencies) {
description: 'Character cards with avatars, traits, and relationships',
category: 'scene',
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)
requiresSchema: false,
+47 -5
View File
@@ -1049,7 +1049,6 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
.rpg-dashboard-container {
display: flex;
flex-direction: column;
gap: 0.75rem;
width: 100%;
flex: 1;
overflow-y: auto;
@@ -1060,7 +1059,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem 0;
padding: 0;
gap: 0.5rem;
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 */
display: flex;
flex-direction: column;
max-height: 100%; /* Prevent content from overflowing grid cell */
/* Unified widget styling - consistent look for all widgets */
background: rgba(0, 0, 0, 0.2);
@@ -1215,6 +1215,9 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
.rpg-widget > * {
box-sizing: border-box;
max-width: 100%;
flex: 1;
min-height: 0;
overflow: auto;
}
.rpg-widget .rpg-stats-content {
@@ -4793,6 +4796,23 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
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 */
.rpg-inventory-subtabs {
display: flex;
@@ -4811,6 +4831,18 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
cursor: pointer;
transition: all 0.2s ease;
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 {
@@ -5352,13 +5384,23 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
/* Mobile Responsive Styles */
@media (max-width: 768px) {
.rpg-inventory-subtabs {
flex-direction: column;
gap: 0.35rem;
flex-direction: row;
gap: 0.5rem;
justify-content: space-between;
}
.rpg-inventory-subtab {
font-size: 1rem;
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 {