diff --git a/RESIZE_HANDLES_INVESTIGATION.md b/RESIZE_HANDLES_INVESTIGATION.md deleted file mode 100644 index 43425d6..0000000 --- a/RESIZE_HANDLES_INVESTIGATION.md +++ /dev/null @@ -1,321 +0,0 @@ -# Resize Handle Overlay Issue - Investigation Report - -## Problem Summary - -The resize handles in edit mode are being rendered **INSIDE the widget container DOM**, causing: -- Widgets to stretch and overflow their grid bounds -- Scrollbars to appear unexpectedly -- Edit/delete buttons to be hidden or inconsistently visible -- Layout overflow issues - -The handles use negative positioning (`top: -6px`, `left: -3px`) to extend outside widget bounds, but being children of the widget element causes them to contribute to the widget's `offsetHeight` and `offsetWidth`, which creates unwanted scrollbars and overflow. - ---- - -## Investigation Findings - -### 1. Where Resize Handles Are Created and Appended - -**File:** `src/systems/dashboard/resizeHandler.js` - -**Key Code (Lines 172-215):** -```javascript -createResizeHandles() { - const container = document.createElement('div'); - container.className = 'resize-handles'; - container.style.position = 'absolute'; - container.style.inset = '0'; - container.style.pointerEvents = 'none'; - - // Create 8 handles (4 corners + 4 edges) - Object.entries(this.handleTypes).forEach(([handleType, cursor]) => { - const handle = document.createElement('div'); - handle.className = `resize-handle resize-handle-${handleType}`; - // ... positioning ... - handle.style.top = '-6px'; // Negative positioning - handle.style.left = '-3px'; // Negative positioning - handle.style.zIndex = '100'; - container.appendChild(handle); - }); - - return container; -} -``` - -**Appended At (Line 77):** -```javascript -initWidget(element, widget, onResizeEnd, constraints = {}) { - const handles = this.createResizeHandles(); - element.appendChild(handles); // <-- APPENDED INSIDE WIDGET - // ... -} -``` - -**Problem:** The handles container is appended directly to the widget element (`element.appendChild(handles)`), making it a child of `.rpg-widget`. - ---- - -### 2. Where Edit/Delete Buttons Are Created - -**File:** `src/systems/dashboard/editModeManager.js` - -**Key Code (Lines 325-373):** -```javascript -addWidgetControls(element, widgetId) { - const controls = document.createElement('div'); - controls.className = 'widget-edit-controls'; - controls.style.position = 'absolute'; - controls.style.top = '4px'; - controls.style.right = '4px'; - controls.style.display = 'flex'; - controls.style.gap = '4px'; - controls.style.zIndex = '100'; - controls.style.opacity = '0'; - controls.style.transition = 'opacity 0.2s'; - - // Create settings and delete buttons - const settingsBtn = this.createControlButton('⚙', 'Settings'); - const deleteBtn = this.createControlButton('×', 'Delete'); - - controls.appendChild(settingsBtn); - controls.appendChild(deleteBtn); - - element.appendChild(controls); // <-- APPENDED INSIDE WIDGET - // ... -} -``` - -**Problem:** Like the resize handles, the edit controls are appended inside the widget element as a child. - ---- - -### 3. Current DOM Structure - -``` -
-``` - -**Why This Causes Issues:** -- Even though handles have `position: absolute`, they're still part of the DOM flow calculation -- Negative positioning extends them outside the widget visually, but the browser still includes them in overflow calculations -- This causes scrollbars when the widget container has `overflow: auto` or `overflow: scroll` -- The controls at `top: 4px; right: 4px` with `z-index: 100` can be covered or hidden by other elements - ---- - -### 4. CSS Widget Styling - -**File:** `style.css` - -**Key Widget CSS:** -```css -.rpg-widget { - box-sizing: border-box; - overflow: visible; /* Allow resize handles to extend beyond widget bounds */ - display: flex; - flex-direction: column; - max-height: 100%; /* Prevent content from overflowing grid cell */ - /* ... other styles ... */ -} - -/* Hide resize handles by default */ -.resize-handles { - opacity: 0; - pointer-events: none; - transition: opacity 0.2s; -} - -/* Show resize handles in edit mode */ -.edit-mode .resize-handles { - opacity: 1; - pointer-events: auto; -} - -/* Hide resize handles when widgets are locked */ -.widgets-locked .resize-handles { - opacity: 0 !important; - pointer-events: none !important; -} -``` - -**Current State:** -- Widget has `overflow: visible` - correct for allowing handles to show -- But the negative positioning of handles inside the widget still causes layout issues -- The `max-height: 100%` on flex column can cause scrollbars if child heights exceed parent - ---- - -### 5. Why Buttons Are Inconsistently Visible - -The edit/delete buttons are positioned inside the widget at `top: 4px; right: 4px;` with `z-index: 100`. Issues arise: - -1. **Scrollbars Overlap:** If the widget develops a scrollbar, the buttons are positioned relative to the widget's content box, not the visible area, so they can be hidden by the scrollbar. - -2. **Parent Stacking Context:** The widget element's positioning and z-index hierarchy may cause the buttons to be layered differently depending on scroll state. - -3. **Hover State Lost:** When scrollbars appear, the widget's visual bounds change, and hover detection may fail to show/hide buttons consistently. - -4. **Absolute Positioning Within Scrollable Parent:** Buttons positioned absolutely within a widget that can scroll create unpredictable rendering. - ---- - -## Recommended Approach: Make Handles & Buttons True Overlays - -### Strategy - -**Move resize handles and edit controls outside the widget DOM to a shared overlay container at the dashboard/grid level.** - -**Current (Problematic) Structure:** -``` - -``` - -**Target (Fixed) Structure:** -``` -