Responsive Grid System - Implementation

Full-featured responsive grid/flexbox system with cell merging and width controls

πŸ“± Responsive Grid System

Professional, full-featured responsive layout builder with cell merging and width controls.


🎯 What We Built

1. Grid Cell Expansion/Merging βœ…

2. Responsive Width Controls βœ…

3. Beautiful Modern UI βœ…


🎨 Grid Cell Merging

How It Works

  1. Enter Grid Edit Mode

    User clicks "Grid Edit" button
    β†’ Beautiful gradient toolbar appears
    β†’ Resize handles become visible on sections
    
  2. Expand a Cell

    User hovers over section
    β†’ Pink/purple handles appear (right, bottom, corner)
    β†’ Handles glow with animation
    
    User clicks handle
    β†’ Cell immediately expands by 1 column/row
    β†’ Smooth transition animation
    β†’ Grid layout updates in real-time
    
  3. Visual Feedback

    .resize-handle {
      background: linear-gradient(135deg, 
        rgba(236, 72, 153, 0.9),  // Pink
        rgba(168, 85, 247, 0.9)   // Purple
      );
      opacity: 0;                  // Hidden by default
      
      &:hover {
        opacity: 1;
        transform: scale(1.1);
        box-shadow: 0 6px 20px rgba(236, 72, 153, 0.6);
      }
    }
    
    .canvas-section:hover .resize-handle {
      opacity: 0.8;
      animation: pulseGlow 2s ease-in-out infinite;
    }
    

Handle Types

Right Handle (Expand Columns)

Bottom Handle (Expand Rows)

Corner Handle (Expand Both)


πŸ“ Responsive System

Breakpoint Structure

// Inspired by editor-web-lib responsive system
export type BreakpointKey = 'base' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';

export interface ResponsiveValue<T> {
  base: T;          // Mobile (0px+)       πŸ”΅
  sm?: T;           // Small (640px+)      πŸ“±
  md?: T;           // Tablet (768px+)     πŸ“±
  lg?: T;           // Laptop (1024px+)    πŸ’»
  xl?: T;           // Desktop (1280px+)   πŸ–₯️
  '2xl'?: T;        // Large (1536px+)     πŸ–₯️
}

Breakpoint Definitions

Breakpoint Label Min Width Icon Device
base Mobile 0px πŸ“± Mobile phones
sm Small 640px πŸ“± Large phones
md Tablet 768px πŸ“± Tablets
lg Laptop 1024px πŸ’» Laptops
xl Desktop 1280px πŸ–₯️ Desktops
2xl Large 1536px πŸ–₯️ Large displays

Utility Functions

Get Value for Breakpoint

import { getResponsiveValue } from '@libs-structural/modular-universe';

const width = getResponsiveValue({
  base: '100%',
  md: '50%',
  lg: '33%'
}, 'lg'); // Returns '33%'

Set Breakpoint Value

import { setBreakpointValue } from '@libs-structural/modular-universe';

const responsive = setBreakpointValue({
  base: '100%'
}, 'md', '50%');

// Result: { base: '100%', md: '50%' }

Check if Responsive

import { isResponsiveValue } from '@libs-structural/modular-universe';

isResponsiveValue({ base: '100%', md: '50%' }); // true
isResponsiveValue('100%'); // false

πŸŽ›οΈ Section Width Controls

Flexbox Sizing Modes

1. Flexible Mode (Default)

{
  sizingMode: 'flexible',
  flexbox: {
    flexGrow: 1,      // How much to grow
    flexShrink: 1,    // How much to shrink
    flexBasis: 'auto' // Base size
  }
}

Use Cases:

2. Fixed Mode

{
  sizingMode: 'fixed',
  width: '250px',     // Fixed width
  minWidth: '200px',  // Minimum width
  maxWidth: '400px'   // Maximum width
}

Use Cases:

Responsive Width Example

// Section with responsive width
{
  width: {
    base: '100%',       // Full width on mobile
    md: '50%',          // Half width on tablet
    lg: '33.333%',      // Third width on desktop
    xl: '300px'         // Fixed 300px on large screens
  },
  minWidth: {
    base: 'auto',
    md: '250px'         // Min 250px on tablet+
  },
  maxWidth: {
    base: '100%',
    lg: '500px'         // Max 500px on laptop+
  }
}

🎨 UI/UX Design

Grid Edit Toolbar

.grid-edit-toolbar {
  // Gradient background (pink β†’ purple)
  background: linear-gradient(135deg, 
    rgba(236, 72, 153, 0.95) 0%,   // #ec4899
    rgba(168, 85, 247, 0.95) 100%  // #a855f7
  );
  
  // Glass morphism
  backdrop-filter: blur(12px);
  box-shadow: 
    0 4px 20px rgba(236, 72, 153, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.15);
  
  // Smooth entrance
  animation: slideInDown 0.3s ease;
}

Export Toolbar

.export-toolbar {
  // Gradient background (cyan β†’ blue)
  background: linear-gradient(135deg,
    rgba(6, 182, 212, 0.95) 0%,    // #06b6d4
    rgba(14, 165, 233, 0.95) 100%  // #0ea5e9
  );
  
  // Same glass effects
  backdrop-filter: blur(12px);
  animation: slideInDown 0.3s ease;
}

Button Styles

.grid-btn {
  // Semi-transparent white background
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 8px;
  
  &:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.25);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  }
  
  &:disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }
}

Done Button

.btn-done {
  // White background with colored text
  background: rgba(255, 255, 255, 0.95);
  color: #ec4899; // Pink text
  font-weight: 700;
  
  &:hover {
    background: white;
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
  }
}

πŸ”„ Integration Points

1. GridCanvasComponent

// Handle span changes from resize handles
handleSpanChange(event: { sectionId: string; colSpan: number; rowSpan: number }): void {
  const config = structuredClone(this.layoutConfig());
  const section = config.sections.find(s => s.id === event.sectionId);
  
  if (section && section.grid) {
    section.grid.colSpan = event.colSpan;
    section.grid.rowSpan = event.rowSpan;
    
    this.layoutConfig.set(config);
    this.scheduleLayoutPersistence();
  }
}

// Update section width (Flexbox)
updateSectionWidth(sectionId: string, width: string): void {
  const section = this.findSection(sectionId);
  section.width = width;
  section.sizingMode = 'fixed';
  this.saveTo();
}

// Update section flex properties
updateSectionFlex(sectionId: string, grow: number, shrink: number, basis: string): void {
  const section = this.findSection(sectionId);
  section.flexbox = { flexGrow: grow, flexShrink: shrink, flexBasis: basis };
  section.sizingMode = 'flexible';
  this.saveToStorage();
}

2. GridSectionComponent

// Emit span change on resize handle click
onResizeStart(event: MouseEvent, direction: 'right' | 'bottom' | 'corner'): void {
  event.preventDefault();
  event.stopPropagation();
  
  const newColSpan = direction === 'right' || direction === 'corner'
    ? this.section.grid!.colSpan + 1
    : this.section.grid!.colSpan;
  
  const newRowSpan = direction === 'bottom' || direction === 'corner'
    ? this.section.grid!.rowSpan + 1
    : this.section.grid!.rowSpan;
  
  this.spanChange.emit({
    sectionId: this.section.id,
    colSpan: newColSpan,
    rowSpan: newRowSpan
  });
}

3. SectionConfigPanelComponent

Already has full width controls:


πŸ“Š User Workflow

Creating a Responsive Sidebar + Content Layout

  1. Switch to Grid Mode

    User clicks "Grid" button
    β†’ Grid initializes as 2Γ—2
    
  2. Enter Grid Edit

    User clicks "Grid Edit"
    β†’ Pink/purple toolbar appears
    β†’ Resize handles become visible
    
  3. Merge First Column (Sidebar)

    User hovers Section 1,1
    β†’ Bottom handle glows
    
    User clicks bottom handle
    β†’ Section expands down (rowSpan = 2)
    β†’ Now spans full left column
    
  4. Configure Sidebar Width

    User clicks Section 1,1
    β†’ Section Config Panel opens
    
    User sets:
    - Sizing Mode: Fixed
    - Width: 250px
    - Min Width: 200px
    - Max Width: 300px
    
  5. Configure Content Area

    User clicks Section 1,2
    β†’ Section Config Panel opens
    
    User sets:
    - Sizing Mode: Flexible
    - Flex Grow: 1 (takes remaining space)
    
  6. Result

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚          β”‚                    β”‚
    β”‚ Sidebar  β”‚  Content (Header)  β”‚
    β”‚ 250px    β”‚  (flexible)        β”‚
    β”‚ (fixed)  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
    β”‚          β”‚                    β”‚
    β”‚          β”‚  Content (Main)    β”‚
    β”‚          β”‚  (flexible)        β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    

πŸŽ“ Best Practices

1. Use Flexible Mode for Responsive Content

{
  sizingMode: 'flexible',
  flexbox: {
    flexGrow: 1,
    flexShrink: 1,
    flexBasis: 'auto'
  }
}

2. Use Fixed Mode for Sidebars/Navigation

{
  sizingMode: 'fixed',
  width: '250px',
  minWidth: '200px',
  maxWidth: '300px'
}

3. Combine Grid + Flexbox for Complex Layouts

// Outer: CSS Grid (2 columns)
{
  type: 'grid',
  grid: {
    columns: ['250px', '1fr'], // Fixed sidebar + flexible content
    rows: ['auto', '1fr']
  }
}

// Inner sections: Use Flexbox for fine-tuning
{
  flexbox: { flexGrow: 1, flexShrink: 0 }
}

4. Use Responsive Values for True Multi-Device Support

{
  width: {
    base: '100%',    // Full width on mobile
    md: '50%',       // Half on tablet
    lg: '250px'      // Fixed on desktop
  }
}

πŸ› Troubleshooting

Resize handles not visible

Cause: Not in grid-edit mode or section is not a grid section
Solution: Click "Grid Edit" button and ensure layout type is "Grid"

Cell not expanding

Cause: Already at maximum span for grid
Solution: Add more rows/columns first, then expand

Width changes not saving

Cause: Auto-save might be delayed (500ms debounce)
Solution: Changes are saved automatically, wait 500ms or click "Done Editing"


πŸŽ‰ Success Metrics


Built with ❀️ for GoGrab Space
The most professional platform builder in the universe.