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
LayoutZone(Model) - Defines a single drop areaLayoutConfig(Model) - Complete layout structureLayoutZoneRendererComponent- Renders zones visuallyUniversalCanvasComponent- 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)
- Drag modules anywhere
- Manual positioning
- No structure constraints
Layout Mode (when layout exists)
- Visual drop zones
- Structured placement
- Type validation per zone
// 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:
- ✅ Green glow = allowed
- ❌ No drop cursor = blocked
🚀 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
- Placeholder text
- Allowed types hint
- Drop icon animation
Drag Over
- Purple glow effect
- Solid border
- Elevated shadow
With Modules
- Compact card view
- Module type icon
- Module name
Required Zones
- Red border (empty)
- Badge indicator
- Must be filled
🔮 Future Enhancements
Phase 2 (Coming Soon)
- ✅ Resizable zones (drag handles)
- ✅ Custom layout builder
- ✅ Zone nesting (zones within zones)
- ✅ Responsive breakpoints
Phase 3 (Future)
- ✅ Animation transitions between layouts
- ✅ Layout presets library
- ✅ Export/import layouts
- ✅ AI-suggested layouts
🏆 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
- Beginners = Guided templates
- Experts = Full programmatic control
🎯 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! 🚀