Skip to content

Latest commit

Β 

History

136 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

EzyTables

A minimalistic, zero-dependency JavaScript/TypeScript library for creating reactive data tables with built-in sorting, searching, and pagination.

npm version License: MIT

πŸ“– Documentation & Demo β†’

Features

  • Zero Dependencies β€” Lightweight (~5KB), no external libraries required
  • Reactive Data β€” Uses Proxy for automatic table updates when data changes
  • Built-in Search β€” Debounced search across all fields (case-insensitive)
  • Column Sorting β€” Sort ascending or descending on any column
  • Pagination β€” Configurable items-per-page with navigation controls
  • Plugin System β€” Transform cell data with custom plugins
  • Custom CSS Classes β€” Full control over table styling
  • Two Modes β€” Works with render functions or by targeting existing HTML tables
  • TypeScript β€” Full type definitions included

Installation

npm install ezytables

Or use via CDN:

<script type="module" src="https://esm.sh/ezytables"></script>

Quick Start

Render Function Mode

import { EzyTables } from "ezytables";

const data = [
  { name: "Alice", email: "alice@example.com", role: "Admin" },
  { name: "Bob", email: "bob@example.com", role: "User" },
  { name: "Charlie", email: "charlie@example.com", role: "Moderator" },
];

const table = new EzyTables({
  data,
  clientEnabled: true,
  client: { perPage: 10 },
  renderFunction: pageData => {
    const tbody = document.querySelector("#myTable tbody");
    tbody.innerHTML = "";
    pageData.forEach(item => {
      const row = document.createElement("tr");
      row.innerHTML = `
        <td>${item.name}</td>
        <td>${item.email}</td>
        <td>${item.role}</td>
      `;
      tbody.appendChild(row);
    });
  },
});

// Search
document.querySelector("#search").addEventListener("input", e => {
  table.setSearchDebounced(e.target.value);
});

// Pagination
document
  .querySelector("#prev")
  .addEventListener("click", () => table.prevPage());
document
  .querySelector("#next")
  .addEventListener("click", () => table.nextPage());

Target Table Mode

Point EzyTables at an existing HTML table and it handles everything:

import { EzyTables } from "ezytables";

const table = new EzyTables({
  target: "#myTable",
  data: myData,
  classes: {
    container: "shadow rounded-lg p-4",
    table: {
      container: "min-w-full",
      thead: { th: "px-3 py-3 text-left text-sm font-semibold" },
      tbody: { td: "px-3 py-4 text-sm" },
    },
  },
});

API Reference

Method Returns Description
new EzyTables(options) EasyTables Create a new table instance
setSearchDebounced(query) void Search with 300ms debounce
sortData(field, order?) void Sort by field ("asc" or "desc")
nextPage() void Go to next page
prevPage() void Go to previous page
goToPage(page) void Jump to a specific page
getCurrentPage() number Get current page number
getTotalPages() number Get total page count
getShowingInfo() string Get display info (e.g., "Showing 1 to 10 of 50 items")
setPerPage(n) void Change items per page
registerPlugin(plugin) void Register a data transform plugin
setData(data) void Replace the data source
getRawData() any[] Get a copy of the raw data
destroy() void Clean up and remove the table

Plugins

Transform cell data before rendering:

const datePlugin = {
  name: "dateFormat",
  field: "date",
  transform: value => {
    return new Date(value).toLocaleDateString("en-US", {
      year: "numeric",
      month: "long",
      day: "numeric",
    });
  },
};

const table = new EzyTables({
  data: myData,
  plugins: [datePlugin],
  target: "#myTable",
});

Constructor Options

interface EasyTablesOptions {
  clientEnabled?: boolean; // Enable client-side mode (default: true)
  data?: any[]; // Data source array
  target?: string; // CSS selector for existing table
  renderFunction?: (data) => void; // Custom render callback
  client?: {
    limit: number;
    perPage?: number; // Items per page (default: 10)
  };
  server?: {
    api_url: string;
    headers?: Record<string, string>;
    limit: number;
    page: number;
    dataNames: string; // Dot-separated path to data in response
  };
  columns?: Column[];
  classes?: Classes; // CSS class overrides
  plugins?: Plugin[]; // Data transform plugins
  hideDetails?: {
    header?: boolean; // Hide search/per-page controls
    footer?: boolean; // Hide pagination footer
  };
  perPageOptions?: number[]; // Custom per-page dropdown options (default: [5, 10, 25, 50, 100])
  onPageChange?: (page: number, totalPages: number) => void;
  onSearch?: (query: string, resultCount: number) => void;
  onSort?: (field: string, order: "asc" | "desc") => void;
  onDataChange?: (newData: any[]) => void;
}

Development

# Install dependencies
npm install

# Start dev server
npm run dev

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Build for production
npm run build

Contributing

See CONTRIBUTING.md for guidelines.

License

MIT Β© Carlos S. Nah

About

Simplify your data management with effortless ease. Experience the power of simplicity, allowing you to organize, analyze, and visualize your data with intuitive features and a clean interface.

Topics

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages