tremor icon indicating copy to clipboard operation
tremor copied to clipboard

How to add pagination to the table?

Open luis-cruzt opened this issue 2 years ago • 5 comments

Is there a way to tremor to handle the pagination or do we need to handle it manually?

Awesome library, keep up the good work

luis-cruzt avatar Jan 20 '23 17:01 luis-cruzt

Hey @luis-cruzt, tremor's table does not support pagination out of the box, you would have to implement this feature yourself. Thanks for using tremor & happy coding 😁

severinlandolt avatar Jan 21 '23 14:01 severinlandolt

Any update? Any help with pagination?

KennStack01 avatar May 12 '23 13:05 KennStack01

This feature would be great

santgr11 avatar May 22 '23 23:05 santgr11

Heya! I am not convinced that a general pagination component makes sense within the table today.

A few thoughts:

  • Would be it a "123 ... 789" or a "show more" component?
  • Should there be a page input field or just left/right buttons?
  • Adding a skip to the end/start button?

There are so many paths ideal pagination could look like. In light of this, I would leave it to the developer to create a pagination specifically tailored to the use case.

One more thing, adding pagination e.g. a property to specify defaultPageSize={n}, so that the table only displays n rows, and adding as many pages as needed. This would change the Table API significantly, basically reducing the table to one component because you have to take care of the pagination logic throughout the component.

severinlandolt avatar May 23 '23 09:05 severinlandolt

Here's an example of how a custom pagination could look like:


import React, { useState } from 'react';


const demoData = [
  { id: 1, name: 'John Doe', age: 25 },
  { id: 2, name: 'Jane Doe', age: 30 },
  { id: 3, name: 'Bob Smith', age: 35 },
  { id: 4, name: 'Alice Johnson', age: 40 },
  { id: 5, name: 'Tom Davis', age: 45 },
  { id: 6, name: 'Sara Lee', age: 50 },
  { id: 7, name: 'Mike Johnson', age: 55 },
  { id: 8, name: 'Mary Johnson', age: 60 },
  { id: 9, name: 'David Smith', age: 65 },
  { id: 10, name: 'Lisa Davis', age: 70 },
  { id: 11, name: 'Mark Johnson', age: 75 },
  { id: 12, name: 'Linda Smith', age: 80 },
  { id: 13, name: 'Peter Lee', age: 85 },
]


function Table({ data, defaultPageSize }) {
  const [currentPage, setCurrentPage] = useState(1);

  function renderTableHeader() {
    return (
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Age</th>
        {data[0]?.email && <th>Email</th>}
      </tr>
    );
  }

  function renderTableData() {
    if (!defaultPageSize) {
      return data.map((item, index) => {
        return (
          <tr key={index}>
            <td>{item.id}</td>
            <td>{item.name}</td>
            <td>{item.age}</td>
            {item.email && <td>{item.email}</td>}
          </tr>
        );
      });
    }

    const startIndex = (currentPage - 1) * defaultPageSize;
    const endIndex = startIndex + defaultPageSize;

    return data.slice(startIndex, endIndex).map((item, index) => {
      return (
        <tr key={index}>
          <td>{item.id}</td>
          <td>{item.name}</td>
          <td>{item.age}</td>
          {item.email && <td>{item.email}</td>}
        </tr>
      );
    });
  }

  function renderPagination() {
    if (!defaultPageSize) return null;

    const totalPages = Math.ceil(data.length / defaultPageSize);
    const startItem = (currentPage - 1) * defaultPageSize + 1;
    const endItem = Math.min(currentPage * defaultPageSize, data.length);

    return (
      <div className="flex justify-between items-center">
        <div>
          Showing {startItem} – {endItem} of {data.length}
        </div>
        <div className="flex">
          <button
            className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none"
            disabled={currentPage === 1}
            onClick={() => setCurrentPage(currentPage - 1)}
          >
            &larr; Prev
          </button>
          <button
            className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none"
            disabled={currentPage === totalPages}
            onClick={() => setCurrentPage(currentPage + 1)}
          >
            Next &rarr;
          </button>
        </div>
      </div>
    );
  }

  return (
    <div>
      <table className="table-auto">
        <thead>{renderTableHeader()}</thead>
        <tbody>{renderTableData()}</tbody>
      </table>
      {renderPagination()}
    </div>
  );
}

severinlandolt avatar May 23 '23 09:05 severinlandolt