WIDGET DUPLICATION FIX

Documentation for Sessions

Widget Duplication Fix - Session 12.14

Problem

When using the Hierarchy section in the Properties Panel to assign a parent to a widget (e.g., moving a Text Widget into a Container Widget), the widget was being rendered twice:

  1. Once on the canvas (as a top-level widget)
  2. Once inside the container (as a child widget)

This caused visual duplication where users would see two copies of the same widget.

Root Cause

The editor-canvas.component.html template was rendering ALL widgets from the widgets() array:

@for (widget of widgets(); track trackByWidgetId($index, widget)) {
  <!-- ... widget rendering ... -->
}

However, when a widget has a parentId, it should:

The canvas was not filtering out child widgets, causing them to be rendered in both places.

Solution

1. Added topLevelWidgets Computed Signal

File: libs/libs-widgets/widgets/src/lib/widgets/editor-canvas/editor-canvas.component.ts

// 🎯 Computed: Only top-level widgets (no parentId) - child widgets are rendered by their containers
readonly topLevelWidgets = computed(() => {
  const allWidgets = this.widgets();
  const topLevel = allWidgets.filter(w => !w.parentId);
  console.log('[Canvas] 🎯 Top-level widgets:', topLevel.length, '/', allWidgets.length);
  return topLevel;
});

This computed signal:

2. Updated Template to Use Top-Level Widgets

File: libs/libs-widgets/widgets/src/lib/widgets/editor-canvas/editor-canvas.component.html

<!-- Widgets (Top-Level Only - children rendered by container widgets) -->
@for (widget of topLevelWidgets(); track trackByWidgetId($index, widget)) {
  <!-- ... widget rendering ... -->
}

Now the canvas only renders top-level widgets. Child widgets are automatically rendered by their parent containers through the existing [childWidgets]="getChildWidgets(widget.id)" mechanism.

Testing

Before Fix

  1. Create a Text Widget on canvas
  2. Open Properties Panel → Hierarchy section
  3. Select "Container Widget" from Parent Widget dropdown
  4. Result: Text widget appears TWICE (once on canvas, once in container)

After Fix

  1. Create a Text Widget on canvas
  2. Open Properties Panel → Hierarchy section
  3. Select "Container Widget" from Parent Widget dropdown
  4. Result: Text widget appears ONCE (only inside the container)
  5. Text widget is removed from top-level canvas rendering

Architecture Notes

Widget Rendering Hierarchy

Canvas (editor-canvas.component)
  └─ Renders: widgets with NO parentId (topLevelWidgets)
      ├─ Text Widget 1 (parentId: undefined) ✅ Rendered by canvas
      ├─ Container Widget (parentId: undefined) ✅ Rendered by canvas
      │    └─ Text Widget 2 (parentId: container.id) ❌ NOT rendered by canvas
      │         └─ Rendered by container via childWidgets ✅
      └─ Button Widget (parentId: undefined) ✅ Rendered by canvas

Key Principles

  1. Canvas renders top-level widgets only (no parentId)
  2. Containers render their own children (via childWidgets prop)
  3. Children are stored in main widgets array but filtered from canvas rendering
  4. Parent-child relationships tracked via parentId and children array

Related Files

Next Steps

Session Progress

Session 12.14 - Fixed widget duplication by implementing topLevelWidgets computed signal.