← Components/Layouts

VirtualList

virtuallist-1779394345472.tsx
'use client'
import { useState, useRef, useMemo } from 'react'

const ITEM_HEIGHT = 56
const VISIBLE_COUNT = 8

const ALL_ITEMS = Array.from({ length: 10000 }, (_, i) => ({
  id: i + 1,
  name: 'Item ' + String(i+1).padStart(4,'0'),
  value: Math.floor(Math.random() * 1000),
}))

export default function VirtualList({ items = ALL_ITEMS }) {
  const [scrollTop, setScrollTop] = useState(0)
  const containerRef = useRef(null)
  const height = VISIBLE_COUNT * ITEM_HEIGHT
  const startIdx = Math.floor(scrollTop / ITEM_HEIGHT)
  const endIdx = Math.min(startIdx + VISIBLE_COUNT + 1, items.length)
  const visibleItems = items.slice(startIdx, endIdx)
  return (
    <div style={{ maxWidth:'360px' }}>
      <div style={{ marginBottom:'8px', fontSize:'13px', color:'#64748b' }}>
        Showing {VISIBLE_COUNT} of <strong>{items.length.toLocaleString()}</strong> items
      </div>
      <div ref={containerRef} onScroll={e=>setScrollTop(e.currentTarget.scrollTop)}
        style={{ height, overflowY:'auto', border:'1px solid #e2e8f0', borderRadius:'12px', position:'relative' }}>
        <div style={{ height:items.length*ITEM_HEIGHT, position:'relative' }}>
          {visibleItems.map((item, i) => (
            <div key={item.id} style={{
              position:'absolute', top:(startIdx+i)*ITEM_HEIGHT,
              left:0, right:0, height:ITEM_HEIGHT,
              display:'flex', alignItems:'center', gap:'12px',
              padding:'0 16px', borderBottom:'1px solid #f1f5f9',
              background:(startIdx+i)%2===0?'#fff':'#fafbfc',
            }}>
              <div style={{ width:'36px', height:'36px', borderRadius:'8px', background:'linear-gradient(135deg,#6d28d9,#2563eb)', display:'flex', alignItems:'center', justifyContent:'center', color:'#fff', fontSize:'10px', fontWeight:700, flexShrink:0 }}>{item.id}</div>
              <span style={{ flex:1, fontWeight:500, color:'#1e293b', fontSize:'14px' }}>{item.name}</span>
              <span style={{ fontWeight:700, color:'#6d28d9', fontSize:'14px' }}>{item.value}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  )
}

Component info

CategoryLayouts
Frameworkreact
TierFREE
Views0
Copies0

About

Virtualized list rendering for thousands of items with windowing

More from Layouts

'use client'
import { useState, useRef, useCallback, useEffect } from 'react'

export default function SplitPane() {
  const [split, setSplit] = useState(50)
  const [dragging, setDragging] = useState(false)
  const [collapsed, setCollapsed] = useSta
SplitPane
Layouts
'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 },
 
GridLayout
Layouts
'use client'
import { useState } from 'react'

const ITEMS = [
  { id: 1, title: 'What is Empire UI?', content: 'Empire UI is a library of 17,500 AI-generated React components.' },
  { id: 2, title: 'How to install?', content: 'Install via npm or use
Accordion
Layouts
'use client'
import { useState } from 'react'

const INIT = [
  { id:1, label:'Design System Audit', priority:'P1' },
  { id:2, label:'API Integration', priority:'P2' },
  { id:3, label:'Performance Review', priority:'P1' },
  { id:4, label:'Mobile R
DragList
Layouts