# All files / components/Pagination Pagination.js

0% Statements 0/67
0% Branches 0/14
0% Functions 0/13
0% Lines 0/29

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126

     import React from 'react';
    import PropTypes from 'prop-types';
    import Icon from '../Icon';
    import PaginationContainer from './styles/PaginationContainer';
    import PaginationItem from './styles/PaginationItem';
    import PaginationItemPlaceholder from './styles/PaginationItemPlaceholder';

    class Pagination extends React.Component {
      static propTypes = {
        /**
         * The number of total pages available.
         */
        pageCount: PropTypes.number,
        /**
         * The currently selected page index.
         */
        currentPage: PropTypes.number,
        /**
         * A callback for page selection. The callback is passed the new selected page index.
         */
        onPageSelected: PropTypes.func.isRequired,
        /**
         * Adds a class name to the pagination container element.
         */
        className: PropTypes.string,
        /**
         * Adds an id to the pagination container element.
         */
        id: PropTypes.string,
        /**
         * A component to render a container for the pagination
         */
        Container: PropTypes.func,
        /**
         * A component to render a single pagination item
         */
        Item: PropTypes.func,
        /**
         * A component to render a placeholder space for a pagination item
         */
        ItemPlaceholder: PropTypes.func,
      };

      static defaultProps = {
        pageCount: 1,
        currentPage: 0,
        className: null,
        id: null,
        Container: PaginationContainer,
        Item: PaginationItem,
        ItemPlaceholder: PaginationItemPlaceholder,
      };

      createItemClickHandler = index => () => this.props.onPageSelected(index);

      handlePreviousClick = () => {
        const { onPageSelected, currentPage } = this.props;
        if (currentPage === 0) {
          return;
        }
        onPageSelected(currentPage - 1);
      };

      handleNextClick = () => {
        const { onPageSelected, currentPage, pageCount } = this.props;
        if (currentPage === pageCount - 1) {
          return;
        }

        onPageSelected(currentPage + 1);
      };

      renderPrevious = () =>
        this.props.currentPage > 0 ? (
          <this.props.Item onClick={this.handlePreviousClick}>
            <Icon name="back" />
          </this.props.Item>
        ) : (
          <this.props.ItemPlaceholder />
        );

      renderNext = () =>
        this.props.currentPage < this.props.pageCount - 1 ? (
          <this.props.Item onClick={this.handleNextClick}>
            <Icon name="forward" />
          </this.props.Item>
        ) : (
          <this.props.ItemPlaceholder />
        );

      renderItems = () => {
        const { pageCount, currentPage, Item } = this.props;
        const start = Math.max(0, Math.min(currentPage + 5, pageCount) - 10);
        const end = Math.min(start + 10, pageCount);
        return (
          new Array(pageCount)
            .fill(null)
            // creates an array of incrementing numbers
            .map((_, index) => index)
            .slice(start, end)
            .map(pageNumber => (
              <Item
                key={pageNumber}
                onClick={this.createItemClickHandler(pageNumber)}
                selected={pageNumber === currentPage}
              >
                {pageNumber + 1}
              </Item>
            ))
        );
      };

      render() {
        const { id, className, Container } = this.props;
        return (
          <Container id={id} className={className}>
            {this.renderPrevious()}
            {this.renderItems()}
            {this.renderNext()}
          </Container>
        );
      }
    }

    export default Pagination;