Skip to content

Component Name: pagination

Last Updated: 2025-09-29 Source Code: https://bitbucket.org/i2cinc/i2c.salesforce.metadata/src/STAGING/force-app/main/default/lwc/pagination

API Name: c-pagination Type: Utility Component Target: lightningCommunity__Page, lightningCommunity__Default

Business Purpose

This reusable pagination component provides navigation controls for paginated lists and tables. It displays First, Previous, page numbers, Next, and Last buttons, allowing users to navigate through large datasets. The component is designed to be embedded in other components that display paginated data.

User Interface

Visual Description

  • Layout: Horizontal button row with page numbers
  • Key UI Elements: Lightning buttons (First, Previous, Next, Last), clickable page number buttons, ellipsis for skipped pages
  • Responsive: Buttons stack on mobile

Screenshots

  • Desktop view: All buttons in a row
  • Mobile view: Buttons may wrap to multiple rows

Component Structure

Files

  • pagination.html - Template/markup
  • pagination.js - JavaScript controller (88 lines)
  • pagination.js-meta.xml - Metadata configuration

HTML Template Structure

<template>
  <div lwc:if={pagesToDisplay.length} class="pagination">
    <lightning-button label="First" onclick={goToFirst} disabled={isFirstPage} />
    <lightning-button label="Previous" onclick={goToPrevious} disabled={isFirstPage} />

    <template if:true={showStartEllipsis}>
      <span class="ellipsis">...</span>
    </template>

    <template for:each={pagesToDisplay} for:item="page">
        <button key={page.page} onclick={handlePageClick}>
          {page.page}
        </button>
    </template>

    <template if:true={showEndEllipsis}>
      <span class="ellipsis">...</span>
    </template>

    <lightning-button label="Next" onclick={goToNext} disabled={isLastPage} />
    <lightning-button label="Last" onclick={goToLast} disabled={isLastPage} />
  </div>
</template>

Key Template Features: - Conditional rendering based on pagesToDisplay.length - Ellipsis shown when pages are skipped - for:each loop for page numbers - CSS classes toggle based on active page

JavaScript Controller

Properties (API)

@api pageRange

  • Type: Number
  • Required: No
  • Default: 5
  • Description: Number of page buttons to display at once (not including First/Previous/Next/Last)

Example Usage:

<c-pagination page-range="7" ...></c-pagination>


@api pageSize

  • Type: Number
  • Required: No
  • Default: 10
  • Description: Number of items per page (used to calculate total pages)

Example Usage:

<c-pagination page-size="20" ...></c-pagination>


@api totalNumber

  • Type: Number
  • Required: Yes
  • Default: 100
  • Description: Total number of items in the dataset

Example Usage:

<c-pagination total-number={totalItems} ...></c-pagination>


@api pageNumber

  • Type: Number
  • Required: No
  • Default: 1
  • Description: Current page number (1-indexed)

Example Usage:

<c-pagination page-number={currentPage} ...></c-pagination>


Tracked Properties

None


Wire Adapters

None


Public Methods

None


Event Handlers

goToFirst

goToFirst() {
    this.updatePage(1);
}

Triggered By: Click on "First" button Event Type: click Action: Navigates to page 1


goToPrevious

goToPrevious() {
    if (!this.isFirstPage) {
        this.updatePage(this.pageNumber - 1);
    }
}

Triggered By: Click on "Previous" button Event Type: click Action: Navigates to previous page


handlePageClick

handlePageClick(event) {
    const page = parseInt(event.currentTarget.dataset.index -+- 1, 10);
    this.updatePage(page);
}

Triggered By: Click on page number button Event Type: click Event Detail: dataset.index contains page index Action: Navigates to clicked page number


goToNext

goToNext() {
    if (!this.isLastPage) {
        this.updatePage(this.pageNumber + 1);
    }
}

Triggered By: Click on "Next" button Event Type: click Action: Navigates to next page


goToLast

goToLast() {
    this.updatePage(this.totalPage);
}

Triggered By: Click on "Last" button Event Type: click Action: Navigates to last page


Private Methods

updatePage

Purpose: Dispatches pagechange event with new page number Called By: All navigation handlers


Events

Events Dispatched

pagechange

const event = new CustomEvent('pagechange', { detail: { pageNumber } });
this.dispatchEvent(event);

Purpose: Notifies parent component of page change When Fired: User clicks any navigation button Event Detail:

{
    pageNumber: 5  // New page number (1-indexed)
}

Handled By: Parent component

Usage in Parent:

<c-pagination onpagechange={handlePageChange} ...></c-pagination>


Events Handled

None


Styling (CSS)

CSS Variables Used

Not specified

Custom CSS Classes

  • .pagination: Container for all pagination controls
  • .page-item: Individual page button
  • .page-item.active: Active/current page button
  • .ellipsis: Ellipsis span styling

SLDS Classes

Lightning buttons use SLDS internally

Responsive Breakpoints

Not explicitly defined - relies on natural button wrapping

Dependencies

Lightning Web Components (Base)

  • lightning-button

Custom LWC Components

None

Apex Classes

None

Salesforce Objects & Fields

None

Static Resources

None

Labels

None

Configuration

Component Meta XML

<targets>
    <target>lightningCommunity__Page</target>
    <target>lightningCommunity__Default</target>
</targets>

Available On: - Community Page - Community Default

Design Properties

None

User Interactions

Actions Available to Users

  1. Navigate to First Page:
  2. Trigger: Click "First" button
  3. Result: Jumps to page 1, dispatches pagechange event

  4. Navigate to Previous Page:

  5. Trigger: Click "Previous" button
  6. Result: Goes back one page, dispatches pagechange event

  7. Navigate to Specific Page:

  8. Trigger: Click page number button
  9. Result: Jumps to that page, dispatches pagechange event

  10. Navigate to Next Page:

  11. Trigger: Click "Next" button
  12. Result: Goes forward one page, dispatches pagechange event

  13. Navigate to Last Page:

  14. Trigger: Click "Last" button
  15. Result: Jumps to last page, dispatches pagechange event

Validation & Error Handling

Client-Side Validation: - First/Previous buttons disabled on first page - Next/Last buttons disabled on last page - Page number parsing validates numeric input

Error Messages: None - component has no error states

Loading States: None

Data Flow

Input Data Flow

Parent provides:
  - totalNumber
  - pageSize
  - pageNumber
Component calculates:
  - totalPage
  - pagesToDisplay
  - isFirstPage / isLastPage
Render buttons

Output Data Flow

User clicks button
updatePage(newPageNumber)
Dispatch pagechange event
Parent component handles event

Performance Considerations

Render Optimization: - Uses getters for computed values (totalPage, pagesToDisplay, etc.) - Conditional rendering hides component if no pages

Data Volume: - Lightweight component, no performance concerns

API Call Optimization: - No API calls

Accessibility (a11y)

ARIA Labels: - Lightning buttons have implicit ARIA labels - Page number buttons need ARIA labels (missing)

Keyboard Navigation: - Tab order follows natural flow - All buttons keyboard accessible

Screen Reader Support: - Button labels announced - Active page state not announced (missing aria-current)

Color Contrast: - Depends on .page-item.active styling - needs verification

Testing

Jest Tests

Test File: None Coverage: 0%

Test Scenarios: - ✗ No tests currently exist

Manual Testing Checklist

  • [ ] First page - Previous/First disabled
  • [ ] Last page - Next/Last disabled
  • [ ] Middle page - all buttons enabled
  • [ ] Page number calculation with various totals
  • [ ] Ellipsis display logic
  • [ ] Click each button type
  • [ ] Keyboard navigation
  • [ ] Screen reader testing

Usage Examples

In Parent Component

<c-pagination
  page-range="5"
  page-size={itemsPerPage}
  total-number={totalItems}
  page-number={currentPage}
  onpagechange={handlePageChange}>
</c-pagination>

Parent Component Handler

handlePageChange(event) {
    this.currentPage = event.detail.pageNumber;
    // Load data for new page
}

Changes & History

  • 2025-09-29: Latest version

⚠️ Pre-Go-Live Concerns

CRITICAL - Fix Before Go-Live

  • Bug in page click handler: Line 69 has -+- operator which is a typo that causes incorrect page calculation: event.currentTarget.dataset.index -+- 1 should be event.currentTarget.dataset.index
  • Missing aria-current: Active page button should have aria-current="page" for accessibility

HIGH - Address Soon After Go-Live

  • No unit tests: Zero test coverage for utility component used in multiple places
  • Console.log in production: Line 39 logs to console
  • Missing ARIA labels: Page number buttons need aria-label="Page X"
  • Page buttons use native HTML: Should use lightning-button for consistency

MEDIUM - Future Enhancement

  • Add keyboard shortcuts: Allow arrow keys for previous/next
  • Add input field: Allow direct page number entry
  • Show page count: Display "Page X of Y"
  • Make button labels configurable: Allow i18n

LOW - Monitor

  • Unused getters: showStartEllipsis and showEndEllipsis logic may not work correctly (lines 49-54)
  • Magic number pageRange default: Could be extracted to constant

Maintenance Notes

Complexity: Low Recommended Review Schedule: Annually

Key Maintainer Notes: - CRITICAL BUG: Line 69 has -+- typo that breaks page clicking - fix immediately - Component used in fellowsSearch and potentially other paginated lists - Simple utility component with minimal dependencies - Focus on accessibility improvements - missing ARIA attributes - Consider adding keyboard shortcuts for power users - Button state management is solid (disabled states work correctly)

Browser Compatibility: - Chrome: Latest - Firefox: Latest - Safari: Latest - Mobile: iOS 12+, Android 8+