feat(dashboard): implement column-aware defaultSize for optimal 3-4 col widget layout
PROBLEM:
- Reset/auto-layout placed userInfo at 1x1, mood at [1,0] blocking expansion
- Expansion pass couldn't grow userInfo to 2x1 because mood already occupied column 1
- Result: 1x1 userInfo, 1x1 mood, empty space at [2,0] in 3-col layout
ROOT CAUSE:
- Static defaultSize 1x1 → placement happens first
- Expansion happens second, but mood blocks userInfo horizontal growth
SOLUTION - Column-aware defaultSize:
1. userInfoWidget.js: defaultSize now function of columns
- Mobile (≤2 col): { w: 1, h: 1 } (compact, mood beside it)
- Desktop (3-4 col): { w: 2, h: 1 } (starts at target size)
2. dashboardManager.js: resetWidgetSizesToDefault() supports function defaultSize
- Calls defaultSize(columns) if function, otherwise uses static object
- Same pattern as maxAutoSize support
3. widgetRegistry.js: Updated validation to accept function defaultSize
- Skip validation for functions (can't validate until runtime)
4. dashboardManager.js: Reordered userWidgetOrder
- mood(2) before stats(3) so mood sits beside userInfo in top row
RESULT (3-4 columns):
- userInfo starts at 2x1, placed at [0,0]
- mood placed at [2,0] (beside 2-wide userInfo)
- stats placed at [0,1] and expands to 3x? (full width below)
- No expansion blocking, no wasted space
MOBILE FIXES (from previous commits):
- Stats widget: padding-bottom 0.5rem (was 0.3rem, prevent Arousal clipping)
- Refresh button: Show with Dashboard v2 (#rpg-dashboard-container selector)
- Mood text: 0.6rem font-size (improve readability)
AFFECTED:
- userInfoWidget.js: defaultSize + maxAutoSize column-aware functions
- dashboardManager.js: resetWidgetSizesToDefault, userWidgetOrder
- widgetRegistry.js: Validation allows function defaultSize
- userStatsWidget.js: maxAutoSize column-aware (previous commit)
- style.css: Stats padding fix 0.5rem
This commit is contained in:
@@ -804,9 +804,9 @@ export class DashboardManager {
|
|||||||
|
|
||||||
// Specific widget type ordering within user category
|
// Specific widget type ordering within user category
|
||||||
const userWidgetOrder = {
|
const userWidgetOrder = {
|
||||||
'userInfo': 1, // Name/level at top
|
'userInfo': 1, // Name/level at top-left
|
||||||
'userStats': 2, // Health/energy bars
|
'userMood': 2, // Mood at top-right (before stats so it sits beside userInfo)
|
||||||
'userMood': 3, // Mood
|
'userStats': 3, // Health/energy bars (after mood, goes below userInfo+mood)
|
||||||
'userAttributes': 4 // STR/DEX/etc
|
'userAttributes': 4 // STR/DEX/etc
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1231,8 +1231,17 @@ export class DashboardManager {
|
|||||||
const definition = this.registry.get(widget.type);
|
const definition = this.registry.get(widget.type);
|
||||||
if (definition && definition.defaultSize) {
|
if (definition && definition.defaultSize) {
|
||||||
const oldSize = `${widget.w}x${widget.h}`;
|
const oldSize = `${widget.w}x${widget.h}`;
|
||||||
widget.w = definition.defaultSize.w;
|
|
||||||
widget.h = definition.defaultSize.h;
|
// Support defaultSize as function (column-aware sizing)
|
||||||
|
let defaultSize;
|
||||||
|
if (typeof definition.defaultSize === 'function') {
|
||||||
|
defaultSize = definition.defaultSize(this.gridEngine.columns);
|
||||||
|
} else {
|
||||||
|
defaultSize = definition.defaultSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
widget.w = defaultSize.w;
|
||||||
|
widget.h = defaultSize.h;
|
||||||
const newSize = `${widget.w}x${widget.h}`;
|
const newSize = `${widget.w}x${widget.h}`;
|
||||||
if (oldSize !== newSize) {
|
if (oldSize !== newSize) {
|
||||||
console.log(`[DashboardManager] Reset ${widget.type} from ${oldSize} to ${newSize}`);
|
console.log(`[DashboardManager] Reset ${widget.type} from ${oldSize} to ${newSize}`);
|
||||||
|
|||||||
@@ -87,7 +87,10 @@ export class WidgetRegistry {
|
|||||||
if (!definition.minSize.w || !definition.minSize.h) {
|
if (!definition.minSize.w || !definition.minSize.h) {
|
||||||
throw new Error('[WidgetRegistry] Widget minSize must have w and h properties');
|
throw new Error('[WidgetRegistry] Widget minSize must have w and h properties');
|
||||||
}
|
}
|
||||||
if (!definition.defaultSize.w || !definition.defaultSize.h) {
|
// defaultSize can be a function (column-aware) or static object
|
||||||
|
if (typeof definition.defaultSize === 'function') {
|
||||||
|
// If function, we can't validate until runtime, skip validation
|
||||||
|
} else if (!definition.defaultSize.w || !definition.defaultSize.h) {
|
||||||
throw new Error('[WidgetRegistry] Widget defaultSize must have w and h properties');
|
throw new Error('[WidgetRegistry] Widget defaultSize must have w and h properties');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,13 +38,19 @@ export function registerUserInfoWidget(registry, dependencies) {
|
|||||||
description: 'User avatar, name, and level display',
|
description: 'User avatar, name, and level display',
|
||||||
category: 'user',
|
category: 'user',
|
||||||
minSize: { w: 1, h: 1 },
|
minSize: { w: 1, h: 1 },
|
||||||
defaultSize: { w: 1, h: 1 }, // Start compact (1x1), expansion will grow it based on columns
|
// Column-aware default size: start at 2x1 in desktop so mood doesn't block expansion
|
||||||
// Column-aware max size: mobile (2-col) stays 1x1, desktop (3-4 col) expands vertically to 1x2
|
defaultSize: (columns) => {
|
||||||
|
if (columns <= 2) {
|
||||||
|
return { w: 1, h: 1 }; // Mobile: compact 1x1
|
||||||
|
}
|
||||||
|
return { w: 2, h: 1 }; // Desktop: 2x1 from the start
|
||||||
|
},
|
||||||
|
// Column-aware max size: same as defaultSize to prevent further expansion
|
||||||
maxAutoSize: (columns) => {
|
maxAutoSize: (columns) => {
|
||||||
if (columns <= 2) {
|
if (columns <= 2) {
|
||||||
return { w: 1, h: 1 }; // Mobile: stay compact to allow mood widget beside it
|
return { w: 1, h: 1 }; // Mobile: stay compact to allow mood widget beside it
|
||||||
}
|
}
|
||||||
return { w: 1, h: 2 }; // Desktop: expand vertically, mood fits top-right
|
return { w: 2, h: 1 }; // Desktop: 2x1, mood sits in top-right
|
||||||
},
|
},
|
||||||
requiresSchema: false,
|
requiresSchema: false,
|
||||||
|
|
||||||
|
|||||||
@@ -4323,7 +4323,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
|
|
||||||
/* User Stats Widget - add bottom padding to prevent last bar (Arousal) from being clipped */
|
/* User Stats Widget - add bottom padding to prevent last bar (Arousal) from being clipped */
|
||||||
.rpg-widget .rpg-stats-grid {
|
.rpg-widget .rpg-stats-grid {
|
||||||
padding-bottom: 0.3rem !important;
|
padding-bottom: 0.5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mood Widget - increase conditions text size for readability */
|
/* Mood Widget - increase conditions text size for readability */
|
||||||
|
|||||||
Reference in New Issue
Block a user