GridLayout
gridlayout-1779379671739.tsx
'use client'
import { useState } from 'react'
interface Block {
id: number
label: string
color: string
colSpan: number
rowSpan: number
}
const INITIAL: Block[] = [
{ id: 1, label: 'Header', color: '#C9A84C', colSpan: 12, rowSpan: 1 },
{ id: 2, label: 'Sidebar', color: '#6366f1', colSpan: 3, rowSpan: 3 },
{ id: 3, label: 'Main Content', color: '#22c55e', colSpan: 9, rowSpan: 2 },
{ id: 4, label: 'Aside', color: '#f59e0b', colSpan: 9, rowSpan: 1 },
{ id: 5, label: 'Footer', color: '#ef4444', colSpan: 12, rowSpan: 1 },
]
export default function GridLayout() {
const [blocks, setBlocks] = useState(INITIAL)
const [selected, setSelected] = useState<number | null>(1)
const sel = blocks.find(b => b.id === selected)
function update(id: number, key: keyof Block, val: number) {
setBlocks(bs => bs.map(b => b.id === id ? { ...b, [key]: Math.max(1, Math.min(key === 'colSpan' ? 12 : 4, val)) } : b))
}
const code = blocks.map(b => `<div style={{ gridColumn: 'span ${b.colSpan}', gridRow: 'span ${b.rowSpan}' }}>
{/* ${b.label} */}
</div>`).join('\n')
return (
<div style={{ background: '#0A0A0A', padding: 24, display: 'flex', flexDirection: 'column', gap: 20 }}>
{/* Controls */}
{sel && (
<div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
<span style={{ color: sel.color, fontSize: 13, fontWeight: 700 }}>{sel.label}</span>
{(['colSpan', 'rowSpan'] as const).map(key => (
<div key={key} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
<span style={{ color: 'rgba(255,255,255,0.4)', fontSize: 12 }}>{key === 'colSpan' ? 'Cols' : 'Rows'}:</span>
<button onClick={() => update(sel.id, key, sel[key] - 1)} style={{ width: 24, height: 24, borderRadius: 5, border: '1px solid rgba(255,255,255,0.1)', background: 'rgba(255,255,255,0.06)', color: '#F5F5F0', cursor: 'pointer', fontSize: 14 }}>−</button>
<span style={{ color: '#F5F5F0', fontSize: 13, minWidth: 16, textAlign: 'center' }}>{sel[key]}</span>
<button onClick={() => update(sel.id, key, sel[key] + 1)} style={{ width: 24, height: 24, borderRadius: 5, border: '1px solid rgba(255,255,255,0.1)', background: 'rgba(255,255,255,0.06)', color: '#F5F5F0', cursor: 'pointer', fontSize: 14 }}>+</button>
</div>
))}
</div>
)}
{/* Grid preview */}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(12, 1fr)', gridAutoRows: '50px', gap: 6 }}>
{blocks.map(b => (
<div key={b.id} onClick={() => setSelected(b.id)}
style={{ gridColumn: `span ${b.colSpan}`, gridRow: `span ${b.rowSpan}`, background: b.color + (selected === b.id ? '30' : '15'), border: `1.5px solid ${b.color}${selected === b.id ? '' : '60'}`, borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', transition: 'all 0.15s' }}>
<span style={{ color: b.color, fontSize: 12, fontWeight: 600 }}>{b.label} ({b.colSpan}×{b.rowSpan})</span>
</div>
))}
</div>
{/* Code output */}
<div style={{ background: '#111', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 10, padding: 14, fontSize: 11, fontFamily: 'monospace', color: 'rgba(255,255,255,0.5)', overflowX: 'auto', whiteSpace: 'pre' }}>
{code}
</div>
</div>
)
}Component info
CategoryLayouts
Frameworkreact
TierFREE
Views0
Copies0
About
Responsive CSS grid layout editor with drag reorder, span controls, and code export