Skip to content

A lightweight, zero-dependency data table with plugin architecture. Sorting, filtering, editing, pagination & more in ~32KB.

License

Notifications You must be signed in to change notification settings

bw-ui/bw-datatable

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@bw-ui/datatable

Production-ready data table with plugin architecture - Zero dependencies, vanilla JavaScript.

Version License Size

Live Demo β€’ Documentation β€’ Plugins

✨ Features

  • πŸͺΆ Lightweight - ~32KB minified, zero dependencies
  • πŸ”Œ Plugin Architecture - Extend with official or custom plugins
  • ✏️ Inline Editing - Double-click to edit cells
  • πŸ” Search & Filter - Global search across all columns
  • ↕️ Sorting - Multi-column sorting support
  • πŸ“„ Pagination - Built-in pagination controls
  • βœ… Selection - Single/multi row selection with checkboxes
  • πŸ“± Responsive - Mobile-friendly design
  • β™Ώ Accessible - Keyboard navigation, ARIA labels
  • 🎨 Themeable - CSS custom properties for styling

πŸ“¦ Installation

npm install @bw-ui/datatable

πŸš€ Quick Start

ES Modules

import { BWDataTable } from '@bw-ui/datatable';
import '@bw-ui/datatable/dist/bw-datatable.min.css';

const table = new BWDataTable('#my-table', {
  data: [
    { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
    { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'Editor' },
    { id: 3, name: 'Bob Wilson', email: 'bob@example.com', role: 'Viewer' },
  ],
});

CDN

<link
  rel="stylesheet"
  href="https://unpkg.com/@bw-ui/datatable/dist/bw-datatable.min.css"
/>
<script src="https://unpkg.com/@bw-ui/datatable/dist/bw-datatable.min.js"></script>

<div id="my-table"></div>

<script>
  const table = new BWDataTable('#my-table', {
    data: [
      { id: 1, name: 'John Doe', email: 'john@example.com' },
      { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
    ],
  });
</script>

βš™οΈ Options

new BWDataTable('#table', {
  // Data
  data: [], // Array of row objects
  columns: null, // Column definitions (auto-detect if null)
  rowId: 'id', // Field to use as row ID

  // Features
  editable: false, // Enable inline editing
  editableColumns: [], // Which columns are editable
  selectable: false, // Enable row selection
  selectionMode: 'multi', // 'single' | 'multi' | 'none'
  sortable: true, // Enable column sorting
  paginated: true, // Enable pagination
  pageSize: 20, // Rows per page
  searchable: true, // Enable global search

  // UI
  showHeader: true, // Show table header
  showFooter: true, // Show pagination footer
  loadingText: 'Loading...', // Loading overlay text
  emptyText: 'No data', // Empty state text

  // Callbacks
  onEditEnd: null, // (rowId, columnId, value, oldValue) => {}
  onSelect: null, // (selectedIds) => {}
  onSort: null, // (column, direction) => {}
  onFilter: null, // (filters) => {}
  onPageChange: null, // (page) => {}
});

Column Definition

{
  columns: [
    {
      id: 'name',              // Unique column ID
      header: 'Full Name',     // Header text
      field: 'name',           // Data field (supports dot notation: 'user.name')
      type: 'string',          // 'string' | 'number' | 'boolean' | 'date'
      width: '200px',          // Column width
      sortable: true,          // Enable sorting for this column
      editable: true,          // Enable editing for this column
      hidden: false,           // Hide column
      render: (value, row) => `<strong>${value}</strong>`,  // Custom renderer
    },
    // ... more columns
  ],
}

πŸ“– Examples

Editable Table

const table = new BWDataTable('#table', {
  data: myData,
  editable: true,
  editableColumns: ['name', 'email', 'role'],
  onEditEnd: (rowId, columnId, value, oldValue) => {
    console.log(`Cell [${rowId}][${columnId}]: ${oldValue} β†’ ${value}`);
    // Save to server...
  },
});

Selectable Table

const table = new BWDataTable('#table', {
  data: myData,
  selectable: true,
  selectionMode: 'multi',
  onSelect: (selectedIds) => {
    console.log('Selected:', selectedIds);
  },
});

// Get selected rows
const selected = table.getSelected();

Custom Column Rendering

const table = new BWDataTable('#table', {
  data: myData,
  columns: [
    { id: 'name', header: 'Name' },
    { id: 'email', header: 'Email' },
    {
      id: 'status',
      header: 'Status',
      render: (value) =>
        value
          ? '<span class="badge green">Active</span>'
          : '<span class="badge red">Inactive</span>',
    },
    {
      id: 'salary',
      header: 'Salary',
      type: 'number',
      render: (value) => `$${value.toLocaleString()}`,
    },
  ],
});

Search & Filter

const table = new BWDataTable('#table', {
  data: myData,
  searchable: true,
});

// Programmatic filtering
table.filter('global', 'john'); // Search all columns
table.filter('role', 'Admin'); // Filter specific column

Sorting

const table = new BWDataTable('#table', {
  data: myData,
  sortable: true,
  onSort: (column, direction) => {
    console.log(`Sorted by ${column} ${direction}`);
  },
});

// Programmatic sorting
table.sort('name', 'asc');
table.sort('salary', 'desc');

πŸ”Œ Plugins

Extend functionality with official plugins:

Package Description Size
@bw-ui/datatable-history Undo/Redo (Ctrl+Z) ~3KB
@bw-ui/datatable-export Export JSON, CSV ~2KB
@bw-ui/datatable-url-state URL sync ~2KB
@bw-ui/datatable-clipboard Copy/Paste Excel ~3KB

Using Plugins

import { BWDataTable } from '@bw-ui/datatable';
import { HistoryPlugin } from '@bw-ui/datatable-history';
import { ExportPlugin } from '@bw-ui/datatable-export';

const table = new BWDataTable('#table', { data: myData })
  .use(HistoryPlugin)
  .use(ExportPlugin);

// Now you have undo/redo and export
table.undo();
table.exportCSV();

πŸ“– API Methods

Data

table.getData(); // Get current rows (filtered/sorted)
table.getOriginalData(); // Get original data
table.setData(newData); // Replace all data
table.addRow(row); // Add single row
table.removeRow(rowId); // Remove row by ID
table.updateRow(rowId, data); // Update row data

Selection

table.getSelected(); // Get selected row objects
table.getSelectedIds(); // Get selected row IDs
table.selectAll(); // Select all visible rows
table.clearSelection(); // Clear selection

Sorting & Filtering

table.sort(column, 'asc'); // Sort by column
table.filter('global', term); // Global search
table.filter(column, value); // Column filter
table.clearFilters(); // Clear all filters

Pagination

table.goToPage(2); // Go to page (0-indexed)
table.setPageSize(50); // Change page size

Editing

table.startEdit(rowId, colId); // Start editing cell
table.setCellValue(rowId, colId, value); // Set cell value

Columns

table.getVisibleColumns(); // Get visible columns
table.hideColumn(colId); // Hide column
table.showColumn(colId); // Show column

Rendering

table.render(); // Re-render table
table.setLoading(true); // Show loading overlay
table.destroy(); // Cleanup and remove

🎨 Theming

Customize with CSS custom properties:

:root {
  /* Colors */
  --bw-dt-bg: #ffffff;
  --bw-dt-text: #1a1a1a;
  --bw-dt-border: #e5e5e5;
  --bw-dt-header-bg: #f8f9fa;
  --bw-dt-row-hover: #f5f5f5;
  --bw-dt-row-selected: #e3f2fd;
  --bw-dt-primary: #2563eb;

  /* Spacing */
  --bw-dt-cell-padding: 12px 16px;
  --bw-dt-border-radius: 8px;

  /* Typography */
  --bw-dt-font-family: system-ui, sans-serif;
  --bw-dt-font-size: 14px;
}

Dark Mode

[data-theme='dark'] {
  --bw-dt-bg: #1a1a1a;
  --bw-dt-text: #e5e5e5;
  --bw-dt-border: #333333;
  --bw-dt-header-bg: #252525;
  --bw-dt-row-hover: #2a2a2a;
  --bw-dt-row-selected: #1e3a5f;
}

⌨️ Keyboard Navigation

Key Action
↑ ↓ ← β†’ Navigate cells
Enter Start editing focused cell
Escape Cancel editing
Tab Move to next cell
Space Toggle row selection
Home / End Jump to first/last cell in row
Ctrl+Home / Ctrl+End Jump to first/last row

πŸ“ What's Included

dist/
β”œβ”€β”€ bw-datatable.min.js       # IIFE build (for <script>)
β”œβ”€β”€ bw-datatable.esm.min.js   # ESM build (for import)
└── bw-datatable.min.css      # Styles

🌐 Browser Support

  • Chrome 80+
  • Firefox 75+
  • Safari 13+
  • Edge 80+

πŸ“„ License

MIT Β© BW UI

πŸ› Issues

Found a bug? Report it here