A simple function for client side pagination

This could be improved in several ways but it’s a decent start:

See the repo here

// @ts-check

/**
 * @typedef OrderByI
 * @property {string} field needs to be a key in `data`
 * @property {'asc' | 'desc'} [sort] defaults to `'asc'`
 */

/**
 * @typedef SearchI
 * @property {string} field needs to be a key in `data`
 * @property {string} [value]
 */

/**
 * Filters, sorts, and slices an array of unknown data type
 * @template {object} T
 * @param {object} params
 * @param {T[]} params.items
 * @param {number} [params.pageNum]
 * @param {number} [params.pageSize]
 * @param {OrderByI} [params.orderBy]
 * @param {SearchI} [params.search]
 * @returns {{items: T[], itemTotal: number}} Paginated data array
 */
export const paginateClientSide = ({
  items,
  pageNum = 1,
  pageSize = 10,
  orderBy,
  search,
}) => {
  let filteredItems = [...items];

  // Apply search filter if provided
  if (search?.field && search.value) {
    filteredItems = filteredItems.filter((item) => {
      if (search.field in item) {
        return (
          // @ts-ignore
          item[search.field]
            .toLowerCase()
            // @ts-ignore
            .includes(search.value.toLowerCase())
        );
      }

      return false;
    });
  }

  // Apply sorting if orderBy is provided
  if (orderBy?.field) {
    filteredItems.sort((a, b) => {
      // @ts-ignore
      const aValue = a[orderBy.field];
      // @ts-ignore
      const bValue = b[orderBy.field];

      if (!orderBy.sort || orderBy.sort === 'asc') {
        if (aValue > bValue) return 1;
        if (aValue < bValue) return -1;
        return 0;
      }

      if (aValue < bValue) return 1;
      if (aValue > bValue) return -1;
      return 0;
    });
  }

  // Apply pagination
  const startIndex = (pageNum - 1) * pageSize;
  const endIndex = startIndex + pageSize;
  const paginatedData = filteredItems.slice(startIndex, endIndex);

  return { items: paginatedData, itemTotal: filteredItems.length };
};

export default paginateClientSide;