CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rc-pagination

pagination ui component for react

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

advanced-customization.mddocs/

Advanced Customization

The rc-pagination component provides extensive customization capabilities including custom renderers, icons, size options, and advanced display controls for sophisticated pagination implementations.

Import

import Pagination from 'rc-pagination';
import type { PaginationProps } from 'rc-pagination';

Custom Renderers

Item Renderer

The itemRender prop allows complete customization of pagination elements including page numbers, navigation buttons, and jump controls.

/**
 * Custom item renderer function
 * @param page - Page number or current page for navigation items
 * @param type - Type of pagination item being rendered
 * @param element - Default element that would be rendered
 * @returns Custom rendered element or null to hide the item
 */
type ItemRender = (
  page: number,
  type: 'page' | 'prev' | 'next' | 'jump-prev' | 'jump-next',
  element: React.ReactNode,
) => React.ReactNode;

Item Types

  • 'page': Individual page number buttons
  • 'prev': Previous page button
  • 'next': Next page button
  • 'jump-prev': Jump to previous group button (...)
  • 'jump-next': Jump to next group button (...)

Size Changer Renderer

The sizeChangerRender prop enables complete customization of the page size selector component.

The sizeChangerRender function receives an info object with the following properties:

/**
 * Size changer render function parameters
 */
interface SizeChangerRenderInfo {
  disabled: boolean;                                    // Whether the size changer is disabled
  size: number;                                        // Current page size
  onSizeChange: (value: string | number) => void;     // Handler for size changes
  'aria-label': string;                               // ARIA label for accessibility
  className: string;                                  // CSS class name
  options: {                                          // Available size options
    label: string;                                    // Display label for the option
    value: string | number;                          // Value for the option
  }[];
}

/**
 * Size changer render function type (exported from rc-pagination)
 */
export type SizeChangerRender = (info: SizeChangerRenderInfo) => React.ReactNode;

Icon Customization

Icon Properties

interface IconProps {
  prevIcon?: React.ComponentType | React.ReactNode;
  nextIcon?: React.ComponentType | React.ReactNode;
  jumpPrevIcon?: React.ComponentType | React.ReactNode;
  jumpNextIcon?: React.ComponentType | React.ReactNode;
}

Each icon prop can accept:

  • React.ReactNode: Static icon element (SVG, span, etc.)
  • React.ComponentType: Dynamic icon component that receives pagination props

Usage Examples

Custom Page Item Renderer

import React from 'react';
import Pagination from 'rc-pagination';

function CustomPageItems() {
  const itemRender = (page, type, element) => {
    switch (type) {
      case 'page':
        return (
          <a 
            className="custom-page-item"
            style={{
              padding: '8px 12px',
              margin: '0 2px',
              border: '1px solid #d9d9d9',
              borderRadius: '4px',
              textDecoration: 'none',
              color: '#333',
            }}
          >
            {page}
          </a>
        );
      
      case 'prev':
        return (
          <a className="custom-prev">
            ← Previous
          </a>
        );
      
      case 'next':
        return (
          <a className="custom-next">
            Next →
          </a>
        );
      
      case 'jump-prev':
        return (
          <a className="custom-jump-prev" title="Previous 5 pages">
            ⋯
          </a>
        );
      
      case 'jump-next':
        return (
          <a className="custom-jump-next" title="Next 5 pages">
            ⋯
          </a>
        );
      
      default:
        return element;
    }
  };

  return (
    <Pagination
      current={5}
      total={500}
      itemRender={itemRender}
      onChange={(page) => console.log('Page:', page)}
    />
  );
}

Custom Size Changer

import React from 'react';
import Pagination from 'rc-pagination';

function CustomSizeChanger() {
  const sizeChangerRender = (info) => {
    const { disabled, size, onSizeChange, options } = info;
    
    return (
      <div className="custom-size-changer">
        <span>Show: </span>
        <select
          value={size}
          disabled={disabled}
          onChange={(e) => onSizeChange(e.target.value)}
          style={{
            padding: '4px 8px',
            border: '1px solid #d9d9d9',
            borderRadius: '4px',
            marginLeft: '4px',
          }}
        >
          {options.map(option => (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          ))}
        </select>
        <span> entries</span>
      </div>
    );
  };

  return (
    <Pagination
      current={1}
      total={1000}
      showSizeChanger
      sizeChangerRender={sizeChangerRender}
      pageSizeOptions={[10, 25, 50, 100]}
      onChange={(page, pageSize) => {
        console.log(`Page: ${page}, Size: ${pageSize}`);
      }}
    />
  );
}

Custom Icons with SVG

import React from 'react';
import Pagination from 'rc-pagination';

const ChevronLeft = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
    <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
  </svg>
);

const ChevronRight = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
    <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
  </svg>
);

const DoubleChevronLeft = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
    <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
    <path d="M22.41 7.41L21 6l-6 6 6 6 1.41-1.41L17.83 12z"/>
  </svg>
);

const DoubleChevronRight = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
    <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
    <path d="M3 6L1.59 7.41 6.17 12l-4.58 4.59L3 18l6-6z"/>
  </svg>
);

function CustomIconPagination() {
  return (
    <Pagination
      current={5}
      total={500}
      prevIcon={<ChevronLeft />}
      nextIcon={<ChevronRight />}
      jumpPrevIcon={<DoubleChevronLeft />}
      jumpNextIcon={<DoubleChevronRight />}
      onChange={(page) => console.log('Page:', page)}
    />
  );
}

Dynamic Icon Components

import React from 'react';
import Pagination from 'rc-pagination';

// Icon component that receives pagination props
const DynamicPrevIcon = (props) => {
  const isFirstPage = props.current === 1;
  return (
    <span style={{ opacity: isFirstPage ? 0.5 : 1 }}>
      ◀ Back
    </span>
  );
};

const DynamicNextIcon = (props) => {
  const isLastPage = props.current === 50; // Assuming 50 total pages
  return (
    <span style={{ opacity: isLastPage ? 0.5 : 1 }}>
      Forward ▶
    </span>
  );
};

function DynamicIconPagination() {
  return (
    <Pagination
      current={1}
      total={500}
      prevIcon={DynamicPrevIcon}
      nextIcon={DynamicNextIcon}
      onChange={(page) => console.log('Page:', page)}
    />
  );
}

Advanced Size Options

Custom Page Size Configuration

import React, { useState } from 'react';
import Pagination from 'rc-pagination';

function AdvancedSizeOptions() {
  const [pageSize, setPageSize] = useState(25);
  
  // Custom size options with labels
  const customSizeOptions = [5, 10, 25, 50, 100, 200];
  
  const buildOptionText = (value) => {
    if (value === 200) return '200 (All)';
    return `${value} per page`;
  };

  return (
    <Pagination
      current={1}
      total={1500}
      pageSize={pageSize}
      pageSizeOptions={customSizeOptions}
      buildOptionText={buildOptionText}
      showSizeChanger
      totalBoundaryShowSizeChanger={20} // Show size changer when total > 20
      onChange={(page, size) => {
        console.log(`Page: ${page}, Size: ${size}`);
        setPageSize(size);
      }}
      onShowSizeChange={(current, size) => {
        console.log(`Size changed to ${size} on page ${current}`);
      }}
    />
  );
}

Conditional Size Changer Display

import React from 'react';
import Pagination from 'rc-pagination';

function ConditionalSizeChanger() {
  const totalItems = 1000;
  const showSizeChangerThreshold = 50;
  
  return (
    <Pagination
      current={1}
      total={totalItems}
      pageSize={10}
      
      // Show size changer only when total exceeds threshold
      showSizeChanger={totalItems > showSizeChangerThreshold}
      
      // Alternative: use built-in boundary
      totalBoundaryShowSizeChanger={showSizeChangerThreshold}
      
      pageSizeOptions={[10, 20, 50, 100]}
      onChange={(page, pageSize) => {
        console.log(`Page: ${page}, Size: ${pageSize}`);
      }}
    />
  );
}

Quick Jumper Customization

Custom Quick Jumper with Go Button

import React from 'react';
import Pagination from 'rc-pagination';

function CustomQuickJumper() {
  return (
    <Pagination
      current={5}
      total={1000}
      
      // Enable quick jumper with custom go button
      showQuickJumper={{
        goButton: 'Jump'
      }}
      
      onChange={(page) => {
        console.log('Jumped to page:', page);
      }}
    />
  );
}

Advanced Quick Jumper

import React from 'react';
import Pagination from 'rc-pagination';

function AdvancedQuickJumper() {
  return (
    <Pagination
      current={10}
      total={2000}
      pageSize={20}
      
      showQuickJumper={{
        goButton: (
          <button 
            type="button"
            style={{
              marginLeft: '8px',
              padding: '4px 12px',
              border: '1px solid #1890ff',
              borderRadius: '4px',
              background: '#1890ff',
              color: 'white',
              cursor: 'pointer',
            }}
          >
            Go →
          </button>
        )
      }}
      
      onChange={(page) => {
        console.log('Navigated to page:', page);
      }}
    />
  );
}

Layout and Styling Customization

CSS Class Customization

import React from 'react';
import Pagination from 'rc-pagination';
import './custom-pagination.css'; // Your custom styles

function StyledPagination() {
  return (
    <Pagination
      current={1}
      total={500}
      
      // Custom CSS classes
      className="my-pagination"
      prefixCls="custom-pagination"
      selectPrefixCls="custom-select"
      
      // Apply styles
      style={{
        marginTop: '20px',
        textAlign: 'center',
        padding: '16px',
        borderRadius: '8px',
        backgroundColor: '#f5f5f5',
      }}
      
      onChange={(page) => console.log('Page:', page)}
    />
  );
}

Alignment Options

import React from 'react';
import Pagination from 'rc-pagination';

function AlignmentExamples() {
  return (
    <div>
      {/* Left aligned (default) */}
      <Pagination
        current={1}
        total={100}
        align="start"
        onChange={() => {}}
      />
      
      {/* Center aligned */}
      <Pagination
        current={1}
        total={100}
        align="center"
        onChange={() => {}}
      />
      
      {/* Right aligned */}
      <Pagination
        current={1}
        total={100}
        align="end"
        onChange={() => {}}
      />
    </div>
  );
}

Advanced Display Options

Compact Layout

import React from 'react';
import Pagination from 'rc-pagination';

function CompactPagination() {
  return (
    <Pagination
      current={10}
      total={1000}
      
      // Show fewer page items for compact display
      showLessItems={true}
      
      // Hide some elements for minimal UI
      showPrevNextJumpers={false}
      showTitle={false}
      
      // Custom compact styling
      style={{ fontSize: '12px' }}
      
      onChange={(page) => console.log('Page:', page)}
    />
  );
}

Mobile-Optimized Simple Mode

import React, { useState, useEffect } from 'react';
import Pagination from 'rc-pagination';

function MobileOptimizedPagination() {
  const [isMobile, setIsMobile] = useState(false);
  
  useEffect(() => {
    const checkMobile = () => {
      setIsMobile(window.innerWidth < 768);
    };
    
    checkMobile();
    window.addEventListener('resize', checkMobile);
    
    return () => window.removeEventListener('resize', checkMobile);
  }, []);

  return (
    <Pagination
      current={5}
      total={500}
      
      // Switch to simple mode on mobile
      simple={isMobile}
      
      // Hide advanced features on mobile
      showSizeChanger={!isMobile}
      showQuickJumper={!isMobile}
      showLessItems={isMobile}
      
      onChange={(page, pageSize) => {
        console.log(`Page: ${page}, Size: ${pageSize}`);
      }}
    />
  );
}

Accessibility Enhancements

Enhanced Accessibility

import React from 'react';
import Pagination from 'rc-pagination';

function AccessiblePagination() {
  return (
    <Pagination
      current={3}
      total={500}
      
      // ARIA attributes
      role="navigation"
      aria-label="Data table pagination"
      
      // Show titles for screen readers
      showTitle={true}
      
      // Custom item renderer with enhanced accessibility
      itemRender={(page, type, element) => {
        const ariaLabels = {
          'page': `Go to page ${page}`,
          'prev': 'Go to previous page',
          'next': 'Go to next page',
          'jump-prev': 'Go to previous 5 pages',
          'jump-next': 'Go to next 5 pages',
        };
        
        return React.cloneElement(element, {
          'aria-label': ariaLabels[type],
          title: ariaLabels[type],
        });
      }}
      
      onChange={(page) => {
        // Announce page change to screen readers
        const announcement = `Page ${page} selected`;
        const ariaLive = document.createElement('div');
        ariaLive.setAttribute('aria-live', 'polite');
        ariaLive.setAttribute('aria-atomic', 'true');
        ariaLive.style.position = 'absolute';
        ariaLive.style.left = '-10000px';
        ariaLive.textContent = announcement;
        document.body.appendChild(ariaLive);
        
        setTimeout(() => {
          document.body.removeChild(ariaLive);
        }, 1000);
      }}
    />
  );
}

Complete Customization Example

import React, { useState } from 'react';
import Pagination from 'rc-pagination';

function FullyCustomizedPagination() {
  const [current, setCurrent] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  
  const itemRender = (page, type, element) => {
    const baseStyle = {
      padding: '8px 12px',
      margin: '0 4px',
      border: '1px solid #d9d9d9',
      borderRadius: '6px',
      background: 'white',
      cursor: 'pointer',
      textDecoration: 'none',
      color: '#333',
      display: 'inline-flex',
      alignItems: 'center',
      fontSize: '14px',
    };
    
    const activeStyle = {
      ...baseStyle,
      background: '#1890ff',
      color: 'white',
      borderColor: '#1890ff',
    };
    
    switch (type) {
      case 'page':
        return (
          <a style={current === page ? activeStyle : baseStyle}>
            {page}
          </a>
        );
      
      case 'prev':
        return (
          <a style={baseStyle}>
            ← Prev
          </a>
        );
      
      case 'next':
        return (
          <a style={baseStyle}>
            Next →
          </a>
        );
        
      default:
        return element;
    }
  };
  
  const sizeChangerRender = (info) => (
    <div style={{ marginLeft: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>
      <span>Show:</span>
      <select
        value={info.size}
        onChange={(e) => info.onSizeChange(e.target.value)}
        style={{
          padding: '4px 8px',
          border: '1px solid #d9d9d9',
          borderRadius: '4px',
        }}
      >
        {info.options.map(option => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    </div>
  );

  return (
    <div style={{ padding: '20px' }}>
      <Pagination
        current={current}
        total={1000}
        pageSize={pageSize}
        
        // Custom renderers
        itemRender={itemRender}
        sizeChangerRender={sizeChangerRender}
        
        // Display options
        showSizeChanger
        showQuickJumper={{ goButton: 'Jump' }}
        showTotal={(total, range) => (
          <div style={{ marginRight: '16px', color: '#666' }}>
            Showing {range[0]}-{range[1]} of {total} items
          </div>
        )}
        
        // Layout
        align="center"
        style={{
          padding: '16px',
          background: '#fafafa',
          borderRadius: '8px',
          border: '1px solid #f0f0f0',
        }}
        
        // Events
        onChange={(page, size) => {
          setCurrent(page);
          setPageSize(size);
          console.log(`Navigate to page ${page} with ${size} items per page`);
        }}
      />
    </div>
  );
}

This comprehensive customization example demonstrates how to combine multiple advanced features for a fully tailored pagination experience.

Install with Tessl CLI

npx tessl i tessl/npm-rc-pagination

docs

advanced-customization.md

index.md

internationalization.md

pagination.md

tile.json