Plan to fix and improve editor web lib
Comprehensive investigation and fix plan for the editor canvas visibility and widget rendering issues
Editor Canvas Investigation - Comprehensive Documentation
Session: 55 (editor2-session-55 branch) Date: January 2026 Status: Investigation complete, implementation deferred to new branch
Table of Contents
- Executive Summary
- Current State & Problems
- Root Cause Analysis
- Key Findings
- Architecture Discovery
- Available Widget Rendering Components
- Critical Code Locations
- Warnings & Things to Watch Out For
- Solution Options
- Recommended Implementation Plan
- Files Reference
- Lessons Learned
Executive Summary
The editor canvas is broken due to a commit (d5fc309c7) that deleted the original EditorCanvasComponent (~1943 lines) and WidgetHostComponent from @libs-widgets/widgets. A simplified replacement was created in editor-ui, but it:
- Renders placeholder divs instead of actual widgets
- Has no drag/resize/move functionality
- Has broken container widget support
- Has debug elements polluting the UI
The fix requires using existing WidgetRendererComponent from @libs-space/universe-canvas or potentially WidgetWrapperComponent from @libs-widgets/widget-adapters.
Current State & Problems
Visual Issues (From Screenshots - January 2026)
URL: localhost:5200/space/chrome-space-1/editor
Debug Elements Polluting UI
- Yellow box: "Active" + "the canvas is rendering correctly!" + "Widgets to render: 14"
- Blue status bar: "| Mode: design | Total: 14 | Top-level: 14 | Width: 768px"
Widget Rendering Issues
- All widgets render as icon placeholders, NOT actual content:
- Container → Purple square icon + "Container" label
- Text → "A" icon + "Text" + "Texto de ejemplo"
- Image → Blue image icon + "Image"
- Card → Red card icon + "Card" + truncated description
- Link → Star icon + "Link"
- Divider → Star icon + "Divider"
- Widgets show type icons instead of actual rendered content
Interaction Issues
- Cannot drag widgets - No move functionality
- Cannot resize widgets - Resize handles visible but non-functional
- Container widget broken - Children not properly contained
What IS Working (Reference Points)
- ✅ Widget Tree panel (right side) - Shows hierarchical structure
- ✅ Properties Panel - Container/Card properties editable
- ✅ Widget Library (left side) - Categories: All, Layout, Content, Interactive, Data Display
- ✅ Selection feedback - Blue border + resize handles appear
- ✅ Container layout options - Flex, Grid, Free modes available
- ✅ Toolbar - Design tools, zoom (69%), grid toggle, layer controls
Widget Library Categories Working
- Layout: Container, Section, Grid
- Content: Text, Heading, Image
- Interactive: Button, Input, Link
- Data Display: Card, List, Table
Technical Issues
- Widgets render as placeholder divs with icons instead of actual widget components
- Position/size reading works but widgets don't have proper rendering
- Selection visual feedback exists but is limited
- No resize handles functionality
- Drag/drop creates widgets but doesn't render them properly
Root Cause Analysis
The Deletion Commit
Commit d5fc309c7 deleted these critical files:
libs/libs-widgets/widgets/src/lib/widgets/editor-canvas/
├── editor-canvas.component.html
├── editor-canvas.component.scss
├── editor-canvas.component.ts (~1943 lines)
└── services/
├── index.ts
├── canvas-selection.service.ts
├── canvas-drag-drop.service.ts
├── canvas-operations.service.ts
└── canvas-layout.service.ts
libs/libs-widgets/widgets/src/lib/widgets/widget-library/
├── widget-library.component.ts (~654 lines)
├── models/widget-library.models.ts
├── services/widget-library.service.ts
└── components/
├── recent-widgets.component.ts
├── widget-item.component.ts
├── widget-search.component.ts
└── widget-category-tabs/
What Made the Original Stable
- Used
WidgetHostComponentfor actual widget rendering (also deleted) - Had dedicated services for canvas operations:
CanvasSelectionService- multi-select, selection stateCanvasDragDropService- drag/drop handlingCanvasOperationsService- CRUD operationsCanvasLayoutService- positioning, constraints
- Properly handled
ResponsiveValue<Position>andResponsiveValue<Size> - Used
getResponsiveValue()helper for breakpoint-aware values
Key Findings
1. Multiple Canvas Components Exist
| Location | Selector | Lines | Interface | Status |
|---|---|---|---|---|
@libs-widgets/widgets (deleted) |
lib-editor-canvas |
~1943 | Widget | ❌ DELETED |
editor-web-lib |
editor-canvas |
~150 | CanvasElement | ✅ Different API |
editor-ui (current) |
lib-editor-canvas |
~380 | Widget | ❌ Broken |
2. Widget Rendering Options Available
Option A: WidgetRendererComponent
- Location:
@libs-space/universe-canvas - Selector:
lib-widget-renderer - Interface: Uses
Widget(same as EditorUiComponent) - Features: Type-specific rendering via ngSwitch
- Limitation: Simpler, doesn't have full design-mode features
Option B: WidgetWrapperComponent
- Location:
@libs-widgets/widget-adapters - Selector:
lib-widget-wrapper - Interface: Uses
WidgetInstance(different fromWidget) - Features: Full design-mode support (drag, resize, select)
- Limitation: Requires converting Widget to WidgetInstance
3. Two Different Widget Interfaces
Widget (from @libs-foundational/core-models):
interface Widget {
id: string;
type: WidgetType;
name: string;
position: ResponsiveValue<Position>; // Breakpoint-aware
size: ResponsiveValue<Size>; // Breakpoint-aware
rotation: ResponsiveValue<number>;
styles: ResponsiveValue<WidgetStyles>;
properties: Record<string, any>;
parentId?: string;
children?: Widget[];
// ... more fields
}
WidgetInstance (from @libs-widgets/widget-adapters):
interface WidgetInstance {
id: string;
type: string;
config: Record<string, unknown>;
position?: { x: number; y: number; width?: number; height?: number }; // Simple
children?: WidgetInstance[];
parentId?: string | null;
// ... more fields
}
4. CUSTOM_ELEMENTS_SCHEMA Masking Errors
The EditorUiComponent uses CUSTOM_ELEMENTS_SCHEMA which suppresses errors for unknown elements. This means components with wrong/missing selectors fail silently.
Architecture Discovery
EditorUiComponent Flow
EditorUiComponent
├── Template expects: <lib-editor-canvas> and <lib-widget-library>
├── Passes: widgets: Widget[], selectedWidgetIds: string[], etc.
├── Uses CUSTOM_ELEMENTS_SCHEMA (suppresses missing component errors)
└── Location: libs/libs-ui/editor-ui/src/lib/components/editor-ui/
Current EditorCanvasComponent (Broken)
EditorCanvasComponent (editor-ui)
├── Selector: lib-editor-canvas
├── Inputs: widgetsInput, selectedWidgetIdsInput, editorModeInput, etc.
├── Outputs: widgetsChange, widgetAction, canvasAction
├── Problem: Renders placeholder divs, not actual widget components
└── Location: libs/libs-ui/editor-ui/src/lib/components/editor-canvas/
Widget Rendering Component Options
WidgetRendererComponent (universe-canvas)
├── Selector: lib-widget-renderer
├── Input: widget: Widget (required)
├── Input: mode: 'preview' | 'edit'
├── Uses ngSwitch for type-specific rendering
├── Has Singularity flow integration
└── Location: libs/libs-space/universe-canvas/src/lib/components/widget-renderer/
WidgetWrapperComponent (widget-adapters)
├── Selector: lib-widget-wrapper
├── Input: instance: WidgetInstance (required)
├── Input: mode: 'design' | 'preview' | 'runtime'
├── Uses UnifiedWidgetRegistry for dynamic rendering
├── Has full drag/resize/select support
└── Location: libs/libs-widgets/widget-adapters/src/lib/components/widget-wrapper/
Available Widget Rendering Components
WidgetRendererComponent Details
File: libs/libs-space/universe-canvas/src/lib/components/widget-renderer/widget-renderer.component.ts
Key Features:
- Uses
Widgetinterface directly - Type-specific templates via ngSwitch for: chart, table, form, hero, button, text, image, card, list
- Singularity flow integration (onClick, onHover, onSubmit events)
- Simple edit/preview mode toggle
Template pattern:
@switch (widget().type) {
@case ('button') { /* button template */ }
@case ('text') { /* text template */ }
// ... more cases
@default { /* generic placeholder */ }
}
WidgetWrapperComponent Details
File: libs/libs-widgets/widget-adapters/src/lib/components/widget-wrapper/widget-wrapper.component.ts
Key Features:
- Uses
WidgetInstanceinterface (needs conversion from Widget) - Dynamic component loading via
UnifiedWidgetRegistry - Full design-mode features:
- Selection handling
- Drag/drop support
- Resize handling
- Child widget management (for containers)
- Error boundary support
- Recursive children rendering
Dynamic rendering pattern:
const componentRef = container.createComponent(widgetDef.component);
Object.entries(inputs).forEach(([key, value]) => {
componentRef.setInput(key, value);
});
Critical Code Locations
Files to Understand
EditorUiComponent (consumer):
libs/libs-ui/editor-ui/src/lib/components/editor-ui/editor-ui.component.tsCurrent EditorCanvasComponent (broken):
libs/libs-ui/editor-ui/src/lib/components/editor-canvas/editor-canvas.component.tsWidget interface:
libs/libs-foundational/core-models/src/lib/types/widget.types.tsWidgetInstance interface:
libs/libs-widgets/widget-adapters/src/lib/models/widget-wrapper.types.tsWidgetRendererComponent (option A):
libs/libs-space/universe-canvas/src/lib/components/widget-renderer/widget-renderer.component.tsWidgetWrapperComponent (option B):
libs/libs-widgets/widget-adapters/src/lib/components/widget-wrapper/widget-wrapper.component.tsUnifiedWidgetRegistry:
libs/libs-widgets/widget-adapters/src/lib/unified/unified-widget-registry.service.ts
Files Created During Investigation (In editor-ui)
libs/libs-ui/editor-ui/src/lib/components/editor-canvas/editor-canvas.component.ts(~380 lines)libs/libs-ui/editor-ui/src/lib/components/editor-canvas/editor-canvas.component.html(~160 lines)libs/libs-ui/editor-ui/src/lib/components/editor-canvas/editor-canvas.component.scss(~364 lines)libs/libs-ui/editor-ui/src/lib/components/editor-canvas/index.tslibs/libs-ui/editor-ui/src/lib/components/widget-library/widget-library.component.ts
Warnings & Things to Watch Out For
⚠️ CRITICAL WARNINGS
DO NOT DELETE
editor-web-libcanvas- Different selector (
editor-canvasvslib-editor-canvas) - Used by different routes/components
- Has its own
CanvasElementinterface
- Different selector (
DO NOT MODIFY
@libs-widgets/widgetsdirectly- User explicitly said: "Only touch the editor-web-lib, not the widgets"
- May break other functionality
CUSTOM_ELEMENTS_SCHEMA hides errors
- Missing components fail silently
- Check browser console for any warnings
- Consider removing schema temporarily during debugging
ResponsiveValue extraction
- Widget uses
ResponsiveValue<Position>with breakpoint keys - Current breakpoint must be extracted:
position.baseorposition.lg, etc. - Helper functions already exist in current component
- Widget uses
Two widget interfaces are incompatible
Widget≠WidgetInstance- Would need conversion function if using WidgetWrapperComponent
⚠️ GOTCHAS DISCOVERED
BreakpointKey mismatch
- Actual type:
'base' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' - NOT:
'mobile' | 'tablet' | 'desktop' | 'wide'
- Actual type:
Widget.config doesn't exist
- Use
widget.propertiesinstead - Properties is
Record<string, any>
- Use
CanvasAction 'add' is invalid
- Use
widgetActionwith type'create'instead
- Use
Property access syntax
- Use
widget.properties?.['label']notwidget.properties.label
- Use
Solution Options
Option A: Use WidgetRendererComponent (Simpler)
Pros:
- Same
Widgetinterface (no conversion needed) - Already has type-specific rendering
- Quick to implement
Cons:
- Limited design-mode features
- No built-in resize/drag handling
- Would need to add interaction features separately
Implementation:
// editor-canvas.component.ts
import { WidgetRendererComponent } from '@libs-space/universe-canvas';
@Component({
imports: [CommonModule, WidgetRendererComponent],
// ...
})
// editor-canvas.component.html
@for (widget of topLevelWidgets(); track widget.id) {
<div class="canvas-widget" [style.left.px]="getWidgetX(widget)" ...>
<lib-widget-renderer
[widget]="widget"
[mode]="isDesignMode() ? 'edit' : 'preview'"
></lib-widget-renderer>
</div>
}
Option B: Use WidgetWrapperComponent (More Complete)
Pros:
- Full design-mode features (drag, resize, select)
- Dynamic component loading
- Handles children recursively
Cons:
- Requires Widget → WidgetInstance conversion
- More complex integration
- May introduce type mismatches
Implementation:
// Would need conversion function
function widgetToInstance(widget: Widget, breakpoint: BreakpointKey): WidgetInstance {
const pos = widget.position[breakpoint] || widget.position.base;
const size = widget.size[breakpoint] || widget.size.base;
return {
id: widget.id,
type: widget.type,
config: widget.properties,
position: { x: pos.x, y: pos.y, width: size.width, height: size.height },
children: widget.children?.map(c => widgetToInstance(c, breakpoint)),
parentId: widget.parentId,
};
}
Option C: Restore Original from Git (Comprehensive)
Pros:
- Gets back full working implementation
- Includes all services and features
Cons:
- Large code restoration (~1943 lines)
- May have dependencies on other deleted code
- User expressed concern about breaking things
Recommended Implementation Plan
Phase 1: Clean Up Current Canvas
- Remove all debug elements from template
- Remove !important hacks from styles
- Keep basic structure working
Phase 2: Integrate Widget Rendering
- Start with Option A (WidgetRendererComponent) for quick wins
- Import from
@libs-space/universe-canvas - Replace placeholder divs with
<lib-widget-renderer> - Verify widgets display correctly
Phase 3: Add Interaction Features
- Add drag handling (can reference WidgetWrapperComponent)
- Add resize handling
- Add proper container support
Phase 4: Polish
- Fix container widget behavior
- Ensure child widgets render inside containers
- Test all widget types
Type Check Command
npx tsc --project libs/libs-ui/editor-ui/tsconfig.lib.json --noEmit
Files Reference
Files TO MODIFY
libs/libs-ui/editor-ui/src/lib/components/editor-canvas/
├── editor-canvas.component.ts # Add WidgetRendererComponent import
├── editor-canvas.component.html # Replace placeholders, remove debug
└── editor-canvas.component.scss # Clean up debug styles
Files NOT TO TOUCH
libs/libs-widgets/widgets/ # User instruction
libs/libs-structural/editor-web-lib/ # Different component
libs/libs-space/universe-canvas/ # Just import from here
Files TO REFERENCE (Read-only)
libs/libs-space/universe-canvas/src/lib/components/widget-renderer/
libs/libs-widgets/widget-adapters/src/lib/components/widget-wrapper/
libs/libs-foundational/core-models/src/lib/types/widget.types.ts
Lessons Learned
- Don't recreate from scratch - Always try to restore from stable first
- Understand the data flow - EditorUiComponent → EditorCanvasComponent → Widget rendering
- Check for existing solutions - WidgetRendererComponent already exists
- CUSTOM_ELEMENTS_SCHEMA is dangerous - Silently hides missing components
- Multiple interfaces exist - Widget vs WidgetInstance, know which you need
- Git history is valuable - Commit
d5fc309c7^has the stable code - User preferences matter - "Only touch editor-web-lib, not widgets"
UI Components Analysis (From Screenshots)
Left Panel: Widget Library ✅ WORKING
The widget library on the left side appears functional:
- Categories tabs: All, Layout, Content, Interactive, Data Display
- Widget items with icons, names, and descriptions
- Good visual hierarchy
- Note: This is likely
WidgetLibraryComponentin editor-ui
Right Panel: Widget Tree & Properties ✅ WORKING
- Widget Tree shows hierarchy correctly
- Properties panel shows when widget selected
- Container properties include: Layout mode (Flex/Grid/Free), Direction, Gap, Align Items, Justify Content
- Card properties include: Hierarchy, Colors, Spacing, Border & Shadow, Size & Position
- Events & Flows section visible
- "Visual Connect" feature for parent-child relationships
Toolbar ✅ WORKING
- Design tools row
- Zoom control (69% visible)
- Grid toggle
- Various action buttons
Canvas Area ❌ BROKEN
- White canvas area renders but widgets show as placeholders
- Debug elements polluting the view
- Selection overlay works but resize handles non-functional
- Drag functionality broken
Key Insight: The Shell is Good, Content Rendering is Broken
The overall editor shell (library, tree, properties, toolbar) is functioning. The core problem is isolated to widget rendering in the canvas area. This confirms the fix should be focused on the EditorCanvasComponent's widget rendering logic.
Priority Fix Order
Based on screenshots and user feedback:
P0: Critical (Must Fix First)
- Remove debug elements (yellow box, blue status bar)
- Fix widget rendering to show actual content (not just icons)
P1: High Priority
- Fix container widget - children should render inside
- Enable widget drag/move functionality
- Enable widget resize functionality
P2: Medium Priority
- Improve widget visual appearance
- Proper hover/selection states
- Responsive preview accuracy
Next Steps for New Session
- Create new branch from current state
- Start with removing debug elements (P0)
- Import and use WidgetRendererComponent for proper widget content (P0)
- Test basic widget rendering
- Fix container widget behavior (P1)
- Add drag/resize functionality (P1)
- Consider Option B (WidgetWrapperComponent) if need full design-mode features
Quick Reference: Key Commit
To see the stable implementation before deletion:
git show d5fc309c7^:libs/libs-widgets/widgets/src/lib/widgets/editor-canvas/editor-canvas.component.ts
This will show the ~1943 line component that was working before.