Layout Zones System

Visual drop zones for structured module placement in the universe canvas

Layout Zones System

🎯 What Are Layout Zones?

Layout Zones transform the universe canvas from a free-form space into a structured visual editor where modules can be placed in predefined areas (zones).

Think of it like Figma's frames or website layout templates - but for building universes!


🏗️ Architecture

Key Components

  1. LayoutZone (Model) - Defines a single drop area
  2. LayoutConfig (Model) - Complete layout structure
  3. LayoutZoneRendererComponent - Renders zones visually
  4. UniversalCanvasComponent - Manages mode switching

Data Flow

Universe Canvas
├─ Detects "Layout" module
│  └─ Extracts config.layoutTemplate
│
├─ Switches to Layout Mode
│  └─ Renders LayoutZoneRendererComponent
│     ├─ Shows visual zones
│     ├─ Handles drag-drop
│     └─ Emits zoneDrop events
│
└─ Creates modules with zone assignment
   └─ Stores zone in config.layoutZone

📦 7 Predefined Templates

1. Header-Main-Footer

Classic 3-row layout (websites, apps)

┌──────────────────┐
│     Header       │ 60px  - Navigation, widgets
├──────────────────┤
│                  │
│       Main       │ Flex  - Main content
│                  │
├──────────────────┤
│     Footer       │ 60px  - Navigation, widgets
└──────────────────┘

2. Sidebar-Main

Left sidebar + main content

┌──────┬───────────┐
│      │           │
│ Side │   Main    │
│ bar  │           │
│      │           │
└──────┴───────────┘
  250px    Flex

3. Main-Sidebar

Main content + right sidebar

┌───────────┬──────┐
│           │      │
│   Main    │ Side │
│           │ bar  │
│           │      │
└───────────┴──────┘
   Flex      250px

4. Two-Column

Equal split (50/50)

┌──────────┬──────────┐
│          │          │
│   Left   │  Right   │
│          │          │
└──────────┴──────────┘
    1fr        1fr

5. Three-Column

Equal thirds (33/33/33)

┌─────┬─────┬─────┐
│     │     │     │
│ L   │  C  │  R  │
│     │     │     │
└─────┴─────┴─────┘
  1fr   1fr   1fr

6. Dashboard-Grid

Grid layout for dashboards

┌──────────────────┐
│    Top Bar       │
├─────────┬────────┤
│  Left   │ Right  │
│  Panel  │ Panel  │
└─────────┴────────┘

7. Hero-Content

Hero section + scrolling content

┌──────────────────┐
│                  │
│       Hero       │ 400px
│                  │
├──────────────────┤
│                  │
│     Content      │ Flex
│                  │
└──────────────────┘

🎨 Zone Properties

Each zone defines:

interface LayoutZone {
  id: string;                    // Unique ID
  name: string;                  // Internal name
  label: string;                 // Display label
  size: ZoneSize;                // '50%' | '200px' | 'flex' | '1fr'
  allowedTypes: string[];        // ['galaxy', 'world', 'widget']
  order: number;                 // Render order
  required?: boolean;            // Must have content?
  placeholder?: string;          // Empty state text
  icon?: string;                 // FontAwesome icon
  minSize?: string;              // Min width/height
  maxSize?: string;              // Max width/height
  cssClasses?: string[];         // Custom styling
}

💾 Data Storage

Layout Module

{
  id: 'mod_layout_123',
  type: 'layout',
  name: 'Main Layout',
  config: {
    layoutTemplate: 'header-main-footer',  // Template key
    gap: '1rem',                           // Optional gap
    showGrid: true,                        // Optional grid
    resizable: false                       // Optional resizing
  }
}

Module in Zone

{
  id: 'mod_galaxy_456',
  type: 'galaxy',
  name: 'Dashboard Galaxy',
  parentId: 'mod_universe_1',
  config: {
    layoutZone: 'main'  // 🎯 Zone assignment!
  }
}

🔄 Mode Switching

The canvas automatically switches between:

Free-Form Mode (default)

Layout Mode (when layout exists)

// Auto-detection in UniversalCanvasComponent
readonly isLayoutMode = computed(() => {
  const layout = this.layoutModule();
  return layout !== null && layout !== undefined;
});

🎯 Type Validation

Each zone restricts which module types can be dropped:

// Example: Header zone
{
  id: 'header',
  allowedTypes: ['navigation', 'widget'],  // ✅ Only these!
  // ❌ Blocks: galaxy, world, page, etc.
}

Visual Feedback:


🚀 How to Use

1. Create Layout

// Drag "Layout" module from library
// Or create programmatically:
moduleService.install(universeId, {
  name: 'Main Layout',
  type: 'layout',
  config: {
    layoutTemplate: 'header-main-footer'
  }
});

2. Canvas Switches to Layout Mode

Zones appear automatically!

3. Drop Modules into Zones

Drag from library → drop in zone → module created with config.layoutZone

4. Query Modules by Zone

import { getModulesInZone } from '@universe-map/models';

const headerModules = getModulesInZone(allModules, 'header');
const mainModules = getModulesInZone(allModules, 'main');

🎨 Visual Features

Empty State

Drag Over

With Modules

Required Zones


🔮 Future Enhancements

Phase 2 (Coming Soon)

Phase 3 (Future)


🏆 Why This Is Powerful

1. Visual Clarity

No more guessing where things go - zones guide users!

2. Structural Integrity

Ensures universes follow best practices and patterns.

3. Reusability

Templates can be shared, cloned, and customized.

4. Flexibility

Visual editor for structure, but API/vibe-coding for advanced use cases.

5. Best of Both Worlds


🎯 The Vision

🌌 Universe Builder
├─ Visual Editor (Layout Zones)
│  └─ Structure, clarity, guidance
│
├─ Vibe Coding (Natural Language)
│  └─ "Add a dashboard with 3 widgets"
│
├─ Singularity (Logic Wiring)
│  └─ Connect data flows between modules
│
└─ API (Programmatic)
   └─ Full control, automation, scripting

Layout Zones = The visual foundation for the most powerful platform builder in the world! 🚀