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:
- Simple: Add rows/cols with one click
- Intuitive: Visual controls, no complex divider logic
- Powerful: Flexbox AND CSS Grid support
- Flutter-Ready: Export production-ready Dart code
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)
- Click sections to select/configure
- View-only, no editing
2. Add Mode
- Click arrows on sections to add before/after
- Quick section creation
3. Resize Mode
- Drag handles to resize sections
- Visual sizing controls
4. Reorder Mode
- Click arrows to move sections up/down
- Reorder sections in place
5. Grid Edit Mode ๐
- Add/Remove Rows: One-click controls
- Add/Remove Columns: One-click controls
- Visual Feedback: See grid dimensions (e.g., "3 ร 4 Grid")
- Auto-Generate Sections: New row/column creates sections automatically
6. Export Mode ๐
- Export to Flutter: Production-ready Dart code
- Export to Web: HTML + CSS code
- Copy JSON: Raw layout configuration
๐งฉ 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
- โ CSS Grid โ GridView.count
- โ Flexbox โ Column/Row
- โ Nested layouts (coming soon)
- โ Responsive sizing (with MediaQuery)
- โ Custom styling (colors, padding, borders)
Export Flow
- User clicks "Export to Flutter"
- FlutterExportService generates Dart code
- Code copied to clipboard automatically
- 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:
- Linear layouts (header, content, footer)
- Responsive flows
- Mobile-first designs
CSS Grid
{
type: 'grid',
grid: {
rows: ['1fr', '2fr', '1fr'],
columns: ['250px', '1fr', '1fr'],
gap: '16px'
},
sections: [...]
}
Use Cases:
- Complex layouts (dashboard, magazine)
- Fixed structures
- Precise positioning
๐พ Storage System
Auto-Save
- Debounced: 500ms after change
- Flash Persistence: Instant sync across tabs
- Real-time MongoDB: Backend persistence
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
- Switch to Grid layout
- Click "Grid Edit" mode
- Add row โ verify 2D grid appears
- Add column โ verify sections created
- Remove row โ verify sections removed
- Remove column โ verify sections removed
- Try removing when 1 row/col โ verify disabled
Export
- Click "Export" mode
- Click "Export to Flutter" โ verify clipboard copy
- Click "Export to Web" โ verify HTML/CSS code
- Click "Copy JSON" โ verify layout JSON
Storage
- Make changes โ verify auto-save (500ms)
- Open in another tab โ verify sync
- Reload page โ verify persistence
๐ Migration Notes
Removed Files
- โ
divider-manager.service.ts - โ
divider-tool.component.ts - โ
divider.types.ts
Added Files
- โ
flutter-export.service.ts
Updated Files
- โ
grid-canvas.component.ts- Complete rewrite - โ
grid-canvas.component.html- Simplified template - โ
canvas-mode.types.ts- New modes (grid-edit,export) - โ
index.ts- Updated exports
๐ฏ Future Enhancements
Phase 1 (Pending)
- Visual cell merge/split
- Flexbox controls (add sections, flex sliders)
- Drag-and-drop section reordering (refine)
Phase 2 (Future)
- React Native export
- SwiftUI export
- Responsive layout profiles (desktop/tablet/mobile)
- Layout templates library
๐ 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
- OnPush Change Detection: Use
cdr.markForCheck()after mutations - Signals: Reactive state with
signal()andcomputed() - Storage System: Flash persistence + real-time sync
- Immutability: Always
structuredClone()before mutations
Related Documentation
๐ Success Criteria
This system is successful when:
- โ Users can create 3ร3 grid in < 10 seconds
- โ Flutter export "just works" every time
- โ No more "divider not moving" bugs
- โ Layout persists across tabs/sessions
- โ 100% TypeScript type safety
Built with โค๏ธ for GoGrab Space
The most professional platform builder in the universe.