npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

auto-scroll-table-react

v0.0.1

Published

A high-performance React auto-scroll table component with fixed header, customizable row count, and hover-to-pause support.

Readme

auto-scroll-table-react

A high-performance React auto-scroll table component with fixed header, virtual scrolling, and hover-to-pause support. Capable of handling 10,000+ rows without DOM bloat.

Features

  • Virtual Scrolling — Only renders visibleRowCount + bufferSize rows in the DOM, regardless of data size
  • Fixed Header — Table header stays fixed while data scrolls
  • Auto Scroll — Automatically scrolls when data exceeds visible row count
  • Seamless Loop — Smooth infinite scrolling with no visual flash on reset
  • Hover to Pause — Scroll pauses on mouse enter, resumes on mouse leave
  • RAF Animation — Scroll animation driven by requestAnimationFrame, decoupled from React render cycle
  • Zero Dependencies — No third-party UI library required
  • TypeScript — Written in TypeScript with full type support

Installation

npm install auto-scroll-table-react

Quick Start

Basic Usage

import { AutoScrollTable } from 'auto-scroll-table-react';

const columns = [
  { key: 'name', title: 'Name', dataIndex: 'name' },
  { key: 'age', title: 'Age', dataIndex: 'age', width: 80 },
  {
    key: 'status',
    title: 'Status',
    render: (value: any, record: any) => <span>{record.status}</span>,
  },
];

const dataSource = [
  { name: 'Alice', age: 25, status: 'Active' },
  { name: 'Bob', age: 30, status: 'Inactive' },
  { name: 'Carol', age: 28, status: 'Active' },
  // ... more rows
];

function App() {
  return (
    <AutoScrollTable
      columns={columns}
      dataSource={dataSource}
      visibleRowCount={5}
      scrollInterval={3000}
      rowHeight={48}
    />
  );
}

Styles are auto-injected — No manual CSS import needed. The component injects its stylesheet into the document <head> automatically on first render.

Large Data — 10,000+ Rows

The component uses virtual scrolling internally. Even with massive datasets, only a handful of DOM nodes are ever rendered.

import { AutoScrollTable } from 'auto-scroll-table-react';

const columns = [
  { key: 'id', title: 'ID', dataIndex: 'id', width: 80 },
  { key: 'value', title: 'Value', dataIndex: 'value' },
];

// 10,000 rows from the server
const bigData = Array.from({ length: 10000 }, (_, i) => ({
  id: i + 1,
  value: `Item ${i + 1}`,
}));

function Dashboard() {
  return (
    <AutoScrollTable
      columns={columns}
      dataSource={bigData}
      visibleRowCount={6}
      scrollInterval={2000}
      rowHeight={40}
      bufferSize={2}
    />
  );
}

Custom Cell Render

Use the render function for full control over cell content.

const columns = [
  {
    key: 'user',
    title: 'User',
    render: (_: any, record: any) => (
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <img src={record.avatar} width={24} height={24} style={{ borderRadius: '50%' }} />
        <span>{record.name}</span>
      </div>
    ),
    width: 150,
  },
  { key: 'email', title: 'Email', dataIndex: 'email' },
  {
    key: 'role',
    title: 'Role',
    dataIndex: 'role',
    align: 'center',
    render: (_: any, record: any) => (
      <span
        style={{
          padding: '2px 8px',
          borderRadius: 4,
          background: record.role === 'Admin' ? '#1890ff' : '#f0f0f0',
          color: record.role === 'Admin' ? '#fff' : '#333',
          fontSize: 12,
        }}
      >
        {record.role}
      </span>
    ),
  },
];

Row Click Handler

<AutoScrollTable
  columns={columns}
  dataSource={dataSource}
  visibleRowCount={5}
  rowHeight={48}
  onRowClick={(record, index) => {
    console.log('Clicked row', index, record);
  }}
/>

Custom Styling

You can pass class names and inline styles to every part of the table.

<AutoScrollTable
  columns={columns}
  dataSource={dataSource}
  visibleRowCount={5}
  rowHeight={48}
  className="my-dashboard-table"
  headerClassName="my-header"
  rowClassName="my-row"
  headerStyle={{ background: '#001529', color: '#fff' }}
  rowStyle={{ fontSize: 13 }}
/>

Override the default SCSS in your own stylesheet:

.my-dashboard-table {
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);

  .auto-scroll-table__header {
    background: #001529;
    color: #fff;
  }

  .auto-scroll-table__row:hover {
    background: #e6f7ff;
  }
}

TypeScript

The component is fully generic. Pass your data type for strict type checking:

interface User {
  id: number;
  name: string;
  age: number;
  status: 'Active' | 'Inactive';
}

const columns = [
  { key: 'name', title: 'Name', dataIndex: 'name' as const },
  { key: 'age', title: 'Age', dataIndex: 'age' as const, width: 80 },
  {
    key: 'status',
    title: 'Status',
    render: (_: any, record: User) => (
      <span style={{ color: record.status === 'Active' ? 'green' : 'red' }}>
        {record.status}
      </span>
    ),
  },
];

<AutoScrollTable<User>
  columns={columns}
  dataSource={users}
  visibleRowCount={5}
  rowHeight={48}
/>

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | columns | Column<T>[] | required | Column definitions | | dataSource | T[] | required | Table data | | visibleRowCount | number | 5 | Number of visible rows | | scrollInterval | number | 3000 | Scroll interval in milliseconds | | rowHeight | number | 48 | Height of each row in pixels | | bufferSize | number | 2 | Extra rows rendered above/below the visible area for smooth scrolling | | className | string | - | Custom class for table wrapper | | style | CSSProperties | - | Custom style for table wrapper | | headerClassName | string | - | Custom class for header | | headerStyle | CSSProperties | - | Custom style for header | | rowClassName | string | - | Custom class for rows | | rowStyle | CSSProperties | - | Custom style for rows | | bodyClassName | string | - | Custom class for body | | bodyStyle | CSSProperties | - | Custom style for body | | onRowClick | (record: T, index: number) => void | - | Row click handler | | emptyText | ReactNode | '暂无数据' | Empty state text |

Column

| Property | Type | Description | |----------|------|-------------| | key | string | Unique key | | title | ReactNode | Header content | | dataIndex | string | Data field key | | width | string \| number | Column width | | align | 'left' \| 'center' \| 'right' | Text alignment | | render | (value, record, index) => ReactNode | Custom cell renderer |

How It Works

  1. Virtual Scrolling — Only visibleRowCount + bufferSize rows exist in the DOM at any time, no matter how large dataSource is.
  2. RAF Animation — The scroll animation is driven by requestAnimationFrame directly updating the DOM transform, completely outside React's render cycle.
  3. React Render FrequencysetState only fires once per scrollInterval (e.g., every 3 seconds) to shift the data window, keeping React diff work trivial.
  4. Seamless Loop — When the animation completes, the data window advances by one row and the transform resets in a useLayoutEffect before the browser paints, producing a visually perfect infinite loop.

Browser Support

Works in all modern browsers that support requestAnimationFrame and CSS transform.

License

MIT