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

poc-table-dragandrop

v0.2.7

Published

Draggable table React component (POC) with reorderable columns

Readme

POC Table Drag and Drop

Minimal Vite + React proof-of-concept demonstrating draggable table rows.

Quick start

cd /Volumes/extended/project/poc-table-dragandrop
npm install
npm run dev

Build

npm run build
npm run preview

Note about dependencies

If you see peer dependency resolution errors during npm install, run:

npm install --legacy-peer-deps

This project uses Vite 5 and @vitejs/plugin-react; some plugin versions may have peer constraints targeting Vite 4.x. Using --legacy-peer-deps is a pragmatic way to install in local dev. For production, prefer aligning plugin versions.

Building the library

This repo includes a small library entry under src/lib/ exporting a DraggableTable component. To build the library bundles (ES / UMD):

npm run build:lib

The output will be in dist/ (files named draggable-table.es.js, draggable-table.umd.js, etc.). React is externalized by default.

Usage examples

Installation:

npm install poc-table-dragandrop antd

Requirements:

  • React ^18.0.0
  • Ant Design ^4.0.0 or ^5.0.0 (for TablePaginationNew component)

1. DraggableTable (Vanilla React)

import { DraggableTable } from 'poc-table-dragandrop'

const columns = [
  { key: 'col1', label: 'Column 1' },
  { key: 'col2', label: 'Column 2' },
  { key: 'col3', label: 'Column 3' },
  { key: 'col4', label: 'Column 4' }
]

const rows = [
  { id: 1, col1: 'A1', col2: 'A2', col3: 'A3', col4: 'A4' },
  { id: 2, col1: 'B1', col2: 'B2', col3: 'B3', col4: 'B4' },
]

function App() {
  return (
    <DraggableTable 
      initialColumns={columns} 
      initialRows={rows}
      freezeLastColumn={true}  // optional: freeze last column
    />
  )
}

2. TablePaginationNew (with Ant Design)

import { TablePaginationNew } from 'poc-table-dragandrop'
import { useState } from 'react'

// Define columns (Ant Design format)
const columns = [
  {
    title: 'Name',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: 'Age',
    dataIndex: 'age',
    key: 'age',
  },
  {
    title: 'Address',
    dataIndex: 'address',
    key: 'address',
  },
]

// Sample data
const data = [
  { key: '1', name: 'John', age: 32, address: 'New York' },
  { key: '2', name: 'Jane', age: 28, address: 'London' },
  // ... more data
]

function App() {
  const [current, setCurrent] = useState(1)
  const [pageSize, setPageSize] = useState(10)

  const handlePageChange = (page, size) => {
    setCurrent(page)
    setPageSize(size)
  }

  return (
    <TablePaginationNew
      dataSource={data}
      columns={columns}
      
      // Pagination
      current={current}
      pageSize={pageSize}
      totalData={100}  // total records (for backend pagination)
      onChange={handlePageChange}
      usePagination={true}
      
      // Features
      enableDragColumn={true}  // ✅ Enable column dragging & resizing
      freezeColumns={[0, 'email']}  // ✅ Freeze columns by index or key
      useSelect={true}         // Show column visibility selector
      loading={false}
      
      // Optional
      type="BE"  // "BE" for backend pagination, "FE" for frontend
      className="custom-class"
      tableScrolled={{ x: 1000, y: 400 }}
      
      // Event handlers
      onSort={(pagination, filters, sorter) => {
        console.log('Sort:', sorter)
      }}
    />
  )
}

Freeze Columns Usage:

The freezeColumns prop supports two formats:

1. Simple Format (all frozen to LEFT):

// Freeze by index
freezeColumns={[0, 1, 2]}

// Freeze by column key/dataIndex
freezeColumns={['id', 'name']}

// Mix index and key
freezeColumns={[0, 'email', 2]}

2. Advanced Format (specify LEFT or RIGHT):

freezeColumns={[
  0,  // Simple: freeze index 0 on left (default)
  'name',  // Simple: freeze 'name' on left (default)
  { index: 2, position: 'left' },  // Freeze by index, specify left
  { key: 'email', position: 'left' },  // Freeze by key, specify left
  { key: 'action', position: 'right' }  // Freeze 'action' column on RIGHT
]}

Features:

  • Frozen columns stick (sticky) when scrolling horizontally
  • Cannot be dragged or reordered
  • Visual indicator: gray background + blue border (left/right based on position)
  • Cursor changes to not-allowed
  • Can still be resized
  • Use with tableScrolled={{ x: <width> }} to enable horizontal scroll

Sort & Filter Usage:

Built-in Column Sorting:

<TablePaginationNew
  enableColumnSorter={true}  // Enable sorting on all columns
  // For Frontend (FE) sorting - automatic
  type="FE"
  
  // For Backend (BE) sorting - handle in onChange
  type="BE"
  onChange={(pagination, filters, sorter) => {
    if (sorter.field) {
      // sorter.field = column dataIndex
      // sorter.order = 'ascend' | 'descend' | undefined
      fetchDataFromAPI({
        page: pagination.current,
        sortField: sorter.field,
        sortOrder: sorter.order
      });
    }
  }}
/>

Built-in Column Filtering:

<TablePaginationNew
  enableColumnFilter={true}  // Enable filtering on all columns
  // Automatically creates:
  // - Dropdown filter for columns with ≤50 unique values
  // - Search filter for columns with >50 values or long text
  
  // For Frontend (FE) - automatic
  type="FE"
  
  // For Backend (BE) - handle in onChange
  type="BE"
  onChange={(pagination, filters, sorter) => {
    // filters = { columnKey: [selectedValues] }
    fetchDataFromAPI({
      page: pagination.current,
      filters: filters
    });
  }}
/>

Disable Sort/Filter for Specific Columns:

const columns = [
  {
    title: 'ID',
    dataIndex: 'id',
    disableSorter: true,   // ❌ No sorting for this column
    disableFilter: true,   // ❌ No filtering for this column
  },
  {
    title: 'Name',
    dataIndex: 'name',
    disableFilter: true,   // ❌ Disable filter only (sorting still enabled)
  },
  {
    title: 'Phone',
    dataIndex: 'phone',
    disableSorter: true,   // ❌ Disable sorting only (filtering still enabled)
  },
  {
    title: 'Email',
    dataIndex: 'email',
    // Both sorting and filtering enabled (default)
  },
]

<TablePaginationNew
  columns={columns}
  enableColumnSorter={true}
  enableColumnFilter={true}
/>
});

}} />


**Migration from onSort:**
```jsx
// OLD (deprecated)
<TablePaginationNew
  onSort={(pagination, filters, sorter) => { /* handle sort */ }}
/>

// NEW (recommended)
<TablePaginationNew
  enableColumnSorter={true}
  onChange={(pagination, filters, sorter) => { 
    // onChange now handles pagination, filters, AND sorting
  }}
/>

Column Resize Usage:

  • When enableDragColumn={true}, a resize handle (⋮) appears at the right edge of each column header
  • Hover over the handle to see it turn blue with a border
  • The cursor will automatically change to resize cursor (col-resize)
  • Click and drag the handle to resize the column (minimum width: 50px)
  • Drag the header center (not the edge) to reorder columns
  • Resize is disabled during column drag to prevent conflicts

All TablePaginationNew Props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | dataSource | array | required | Data array for table | | columns | array | required | Ant Design column definitions | | enableDragColumn | boolean | false | Enable column drag, reorder & resize | | enableColumnSorter | boolean | false | Enable built-in column sorting | | enableColumnFilter | boolean | false | Enable built-in column filtering | | freezeColumns | array | - | Array of column indices or keys to freeze | | current | number | - | Current page number | | pageSize | number | - | Items per page | | totalData | number | - | Total records (for BE pagination) | | onChange | function | - | Callback for pagination, filter, sort changes | | usePagination | boolean | true | Show pagination | | useSelect | boolean | true | Show column selector | | type | "BE" \| "FE" | "BE" | Pagination type | | loading | boolean | false | Loading state | | tableScrolled | object | - | Scroll config {x, y} | | className | string | - | Custom CSS class | | onSort | function | - | Sort callback | | rowSelection | object | - | Ant Design row selection | | expandable | object | - | Ant Design expandable config |

Manual CSS import (if needed):

import 'poc-table-dragandrop/dist/draggable-table.css'
```UMD usage via script tag (React must be provided globally):

```html
<script src="https://unpkg.com/react/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
<script src="/path/to/dist/draggable-table.umd.js"></script>
<script>
	const { DraggableTable } = window.DraggableTable
	// render with ReactDOM
</script>

Publishing to npm

  1. Fill package.json metadata fields: author, repository.url, and confirm name is unique on npm.
  2. Build the library (prepare script runs automatically on publish):
npm run build:lib
  1. Login and publish:
npm login
npm publish --access public

After publishing, other projects can install:

npm install poc-table-dragandrop