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

  1. Executive Summary
  2. Current State & Problems
  3. Root Cause Analysis
  4. Key Findings
  5. Architecture Discovery
  6. Available Widget Rendering Components
  7. Critical Code Locations
  8. Warnings & Things to Watch Out For
  9. Solution Options
  10. Recommended Implementation Plan
  11. Files Reference
  12. 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:

  1. Renders placeholder divs instead of actual widgets
  2. Has no drag/resize/move functionality
  3. Has broken container widget support
  4. 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

Widget Rendering Issues

Interaction Issues

  1. Cannot drag widgets - No move functionality
  2. Cannot resize widgets - Resize handles visible but non-functional
  3. Container widget broken - Children not properly contained

What IS Working (Reference Points)

Widget Library Categories Working

Technical Issues

  1. Widgets render as placeholder divs with icons instead of actual widget components
  2. Position/size reading works but widgets don't have proper rendering
  3. Selection visual feedback exists but is limited
  4. No resize handles functionality
  5. 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

  1. Used WidgetHostComponent for actual widget rendering (also deleted)
  2. Had dedicated services for canvas operations:
    • CanvasSelectionService - multi-select, selection state
    • CanvasDragDropService - drag/drop handling
    • CanvasOperationsService - CRUD operations
    • CanvasLayoutService - positioning, constraints
  3. Properly handled ResponsiveValue<Position> and ResponsiveValue<Size>
  4. 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

Option B: WidgetWrapperComponent

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:

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:

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

  1. EditorUiComponent (consumer): libs/libs-ui/editor-ui/src/lib/components/editor-ui/editor-ui.component.ts

  2. Current EditorCanvasComponent (broken): libs/libs-ui/editor-ui/src/lib/components/editor-canvas/editor-canvas.component.ts

  3. Widget interface: libs/libs-foundational/core-models/src/lib/types/widget.types.ts

  4. WidgetInstance interface: libs/libs-widgets/widget-adapters/src/lib/models/widget-wrapper.types.ts

  5. WidgetRendererComponent (option A): libs/libs-space/universe-canvas/src/lib/components/widget-renderer/widget-renderer.component.ts

  6. WidgetWrapperComponent (option B): libs/libs-widgets/widget-adapters/src/lib/components/widget-wrapper/widget-wrapper.component.ts

  7. UnifiedWidgetRegistry: libs/libs-widgets/widget-adapters/src/lib/unified/unified-widget-registry.service.ts

Files Created During Investigation (In editor-ui)


Warnings & Things to Watch Out For

⚠️ CRITICAL WARNINGS

  1. DO NOT DELETE editor-web-lib canvas

    • Different selector (editor-canvas vs lib-editor-canvas)
    • Used by different routes/components
    • Has its own CanvasElement interface
  2. DO NOT MODIFY @libs-widgets/widgets directly

    • User explicitly said: "Only touch the editor-web-lib, not the widgets"
    • May break other functionality
  3. CUSTOM_ELEMENTS_SCHEMA hides errors

    • Missing components fail silently
    • Check browser console for any warnings
    • Consider removing schema temporarily during debugging
  4. ResponsiveValue extraction

    • Widget uses ResponsiveValue<Position> with breakpoint keys
    • Current breakpoint must be extracted: position.base or position.lg, etc.
    • Helper functions already exist in current component
  5. Two widget interfaces are incompatible

    • Widget ≠ WidgetInstance
    • Would need conversion function if using WidgetWrapperComponent

⚠️ GOTCHAS DISCOVERED

  1. BreakpointKey mismatch

    • Actual type: 'base' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
    • NOT: 'mobile' | 'tablet' | 'desktop' | 'wide'
  2. Widget.config doesn't exist

    • Use widget.properties instead
    • Properties is Record<string, any>
  3. CanvasAction 'add' is invalid

    • Use widgetAction with type 'create' instead
  4. Property access syntax

    • Use widget.properties?.['label'] not widget.properties.label

Solution Options

Option A: Use WidgetRendererComponent (Simpler)

Pros:

Cons:

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:

Cons:

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:

Cons:


Recommended Implementation Plan

Phase 1: Clean Up Current Canvas

  1. Remove all debug elements from template
  2. Remove !important hacks from styles
  3. Keep basic structure working

Phase 2: Integrate Widget Rendering

  1. Start with Option A (WidgetRendererComponent) for quick wins
  2. Import from @libs-space/universe-canvas
  3. Replace placeholder divs with <lib-widget-renderer>
  4. Verify widgets display correctly

Phase 3: Add Interaction Features

  1. Add drag handling (can reference WidgetWrapperComponent)
  2. Add resize handling
  3. Add proper container support

Phase 4: Polish

  1. Fix container widget behavior
  2. Ensure child widgets render inside containers
  3. 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

  1. Don't recreate from scratch - Always try to restore from stable first
  2. Understand the data flow - EditorUiComponent → EditorCanvasComponent → Widget rendering
  3. Check for existing solutions - WidgetRendererComponent already exists
  4. CUSTOM_ELEMENTS_SCHEMA is dangerous - Silently hides missing components
  5. Multiple interfaces exist - Widget vs WidgetInstance, know which you need
  6. Git history is valuable - Commit d5fc309c7^ has the stable code
  7. 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:

Right Panel: Widget Tree & Properties ✅ WORKING

Toolbar ✅ WORKING

Canvas Area ❌ 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)

  1. Remove debug elements (yellow box, blue status bar)
  2. Fix widget rendering to show actual content (not just icons)

P1: High Priority

  1. Fix container widget - children should render inside
  2. Enable widget drag/move functionality
  3. Enable widget resize functionality

P2: Medium Priority

  1. Improve widget visual appearance
  2. Proper hover/selection states
  3. Responsive preview accuracy

Next Steps for New Session

  1. Create new branch from current state
  2. Start with removing debug elements (P0)
  3. Import and use WidgetRendererComponent for proper widget content (P0)
  4. Test basic widget rendering
  5. Fix container widget behavior (P1)
  6. Add drag/resize functionality (P1)
  7. 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.