Grid Canvas System - Professional Layout Builder

Simple, powerful grid/flexbox layout builder with Flutter export

๐ŸŽจ Grid Canvas System

The most professional, intuitive grid/flexbox builder for GoGrab Space.

๐ŸŽฏ Overview

The Grid Canvas System is a complete rewrite of the layout builder, designed to be:

Removed: โŒ Complex Divider System

Added: โœ… Simple Grid Controls + Flutter Export


๐Ÿ“ File Structure

libs/libs-structural/modular-universe/
โ”œโ”€โ”€ src/lib/
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ””โ”€โ”€ grid-canvas/
โ”‚   โ”‚       โ”œโ”€โ”€ grid-canvas.component.ts      # Main canvas logic
โ”‚   โ”‚       โ”œโ”€โ”€ grid-canvas.component.html    # Template
โ”‚   โ”‚       โ””โ”€โ”€ grid-canvas.component.scss    # Styles
โ”‚   โ”œโ”€โ”€ services/
โ”‚   โ”‚   โ””โ”€โ”€ flutter-export.service.ts         # Flutter code generation
โ”‚   โ””โ”€โ”€ models/
โ”‚       โ”œโ”€โ”€ layout-types.ts                   # Layout interfaces
โ”‚       โ””โ”€โ”€ canvas-mode.types.ts              # Canvas modes

๐ŸŽฎ Canvas Modes

1. Select Mode (Default)

2. Add Mode

3. Resize Mode

4. Reorder Mode

5. Grid Edit Mode ๐Ÿ†•

6. Export Mode ๐Ÿ†•


๐Ÿงฉ Grid Edit Mode - How It Works

Adding Rows/Columns

// User clicks "Add Row"
addGridRow() {
  // 1. Add new row track (1fr)
  config.grid.rows.push('1fr');
  
  // 2. Create sections for new row (one per column)
  for (col = 1; col <= colCount; col++) {
    createGridSection(newRowIndex, col);
  }
  
  // 3. Save to storage
  saveLayoutConfiguration();
}

Result: Instant visual update, new sections ready for content.

Removing Rows/Columns

// User clicks "Remove Row"
removeGridRow() {
  // 1. Remove last row track
  config.grid.rows.pop();
  
  // 2. Remove sections in that row
  config.sections = config.sections.filter(
    section => section.grid.row !== removedRowIndex
  );
  
  // 3. Save to storage
  saveLayoutConfiguration();
}

Safety: Can't remove if only 1 row/column remains.


๐Ÿš€ Flutter Export System

Usage

// User clicks "Export to Flutter"
const flutterCode = flutterExport.exportLayout(layoutConfig);

// Output:
GridView.count(
  crossAxisCount: 3,
  crossAxisSpacing: 16,
  mainAxisSpacing: 16,
  children: [
    Container(
      decoration: BoxDecoration(
        color: Colors.grey[200],
        borderRadius: BorderRadius.circular(8.0),
      ),
      padding: EdgeInsets.all(16.0),
      child: Text('Section 1'),
    ),
    // ... more sections
  ],
)

Supported Features

Export Flow

  1. User clicks "Export to Flutter"
  2. FlutterExportService generates Dart code
  3. Code copied to clipboard automatically
  4. Alert confirms "Flutter code copied!"

๐ŸŽจ Layout Types

Flexbox (Default)

{
  type: 'flexbox',
  flexbox: {
    direction: 'column',
    wrap: 'nowrap',
    justifyContent: 'flex-start',
    alignItems: 'stretch',
    gap: '16px'
  },
  sections: [...]
}

Use Cases:

CSS Grid

{
  type: 'grid',
  grid: {
    rows: ['1fr', '2fr', '1fr'],
    columns: ['250px', '1fr', '1fr'],
    gap: '16px'
  },
  sections: [...]
}

Use Cases:


๐Ÿ’พ Storage System

Auto-Save

Storage Key Pattern

const key = `modular-universe/layout/${universeId}/${moduleType}`;
// Example: "modular-universe/layout/main-universe/universe"

Event System

// Listen for cross-tab updates
this.storage.onEvent((event) => {
  if (event.type === 'put' && event.key === layoutKey) {
    // Reload layout from storage
    this.layoutConfig.set(updatedConfig);
  }
});

๐Ÿ›ก๏ธ Prevents Loops: Ignores own save events with isSaving flag.


๐Ÿงช Testing Guide

Manual Testing Checklist

Grid Mode

Export

Storage


๐Ÿ”„ Migration Notes

Removed Files

Added Files

Updated Files


๐ŸŽฏ Future Enhancements

Phase 1 (Pending)

Phase 2 (Future)


๐Ÿ“š Code Examples

Creating a Simple 2x2 Grid

// User switches to Grid mode
switchLayoutType('grid');

// System auto-generates 2x2 grid
{
  type: 'grid',
  grid: {
    rows: ['1fr', '1fr'],
    columns: ['1fr', '1fr'],
    gap: '16px'
  },
  sections: [
    { id: '1', grid: { row: 1, col: 1, rowSpan: 1, colSpan: 1 } },
    { id: '2', grid: { row: 1, col: 2, rowSpan: 1, colSpan: 1 } },
    { id: '3', grid: { row: 2, col: 1, rowSpan: 1, colSpan: 1 } },
    { id: '4', grid: { row: 2, col: 2, rowSpan: 1, colSpan: 1 } }
  ]
}

Adding a Third Column

// User clicks "Add Column" in Grid Edit mode
addGridColumn();

// System adds column and creates 2 new sections (for 2 rows)
{
  grid: {
    columns: ['1fr', '1fr', '1fr']  // Added '1fr'
  },
  sections: [
    // ... existing 4 sections
    { id: '5', grid: { row: 1, col: 3, rowSpan: 1, colSpan: 1 } },
    { id: '6', grid: { row: 2, col: 3, rowSpan: 1, colSpan: 1 } }
  ]
}

๐Ÿ› Troubleshooting

Grid sections not appearing

Cause: Sections array empty
Solution: Switch to Grid mode to auto-generate default sections

Export button not copying

Cause: Browser clipboard permissions
Solution: Check console for code output, copy manually

Layout not persisting

Cause: universeId not set
Solution: Verify universeId input is provided to component

Cross-tab sync not working

Cause: Storage event listener not registered
Solution: Check console logs for event listener setup


๐ŸŽ“ Learning Resources

Key Concepts

  1. OnPush Change Detection: Use cdr.markForCheck() after mutations
  2. Signals: Reactive state with signal() and computed()
  3. Storage System: Flash persistence + real-time sync
  4. Immutability: Always structuredClone() before mutations

Related Documentation


๐ŸŽ‰ Success Criteria

This system is successful when:


Built with โค๏ธ for GoGrab Space
The most professional platform builder in the universe.