All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.src.components.Pagination.Navigation.tsx Maven / Gradle / Ivy

Go to download

This library provides a set of common React components for use with the PatternFly reference implementation.

The newest version!
import * as React from 'react';
import styles from '@patternfly/react-styles/css/components/Pagination/pagination';
import { css } from '@patternfly/react-styles';
import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-right-icon';
import { Button, ButtonVariant } from '../Button';
import { TextInput } from '../TextInput';
import { OnSetPage } from './Pagination';
import { pluralize, PickOptional } from '../../helpers';
import { KeyTypes } from '../../helpers/constants';

export interface NavigationProps extends React.HTMLProps {
  /** Additional classes for the pagination navigation container. */
  className?: string;
  /** Accessible label for the input displaying the current page. */
  currPageAriaLabel?: string;
  /** The number of first page where pagination starts. */
  firstPage?: number;
  /** Flag indicating if the pagination is compact. */
  isCompact?: boolean;
  /** Flag indicating if the pagination is disabled. */
  isDisabled?: boolean;
  /** Total number of items. */
  itemCount?: number;
  /** The number of the last page. */
  lastPage?: number;
  /** Label for the English word "of". */
  ofWord?: string;
  /** The number of the current page. */
  page: string | number;
  /** The title of a page displayed beside the page number. */
  pagesTitle?: string;
  /** The title of a page displayed beside the page number (the plural form). */
  pagesTitlePlural?: string;
  /** Accessible label for the pagination component. */
  paginationAriaLabel?: string;
  /** Number of items per page. */
  perPage?: number;
  /** Accessible label for the button which moves to the first page. */
  toFirstPageAriaLabel?: string;
  /** Accessible label for the button which moves to the last page. */
  toLastPageAriaLabel?: string;
  /** Accessible label for the button which moves to the next page. */
  toNextPageAriaLabel?: string;
  /** Accessible label for the button which moves to the previous page. */
  toPreviousPageAriaLabel?: string;
  /** Function called when user clicks to navigate to first page. */
  onFirstClick?: (event: React.SyntheticEvent, page: number) => void;
  /** Function called when user clicks to navigate to last page. */
  onLastClick?: (event: React.SyntheticEvent, page: number) => void;
  /** Function called when user clicks to navigate to next page. */
  onNextClick?: (event: React.SyntheticEvent, page: number) => void;
  /** Function called when user clicks to navigate to previous page. */
  onPreviousClick?: (event: React.SyntheticEvent, page: number) => void;
  /** Function called when user inputs page number. */
  onPageInput?: (event: React.SyntheticEvent, page: number) => void;
  /** Function called when page is changed. */
  onSetPage: OnSetPage;
}

export interface NavigationState {
  userInputPage?: React.ReactText;
}

class Navigation extends React.Component {
  static displayName = 'Navigation';
  constructor(props: NavigationProps) {
    super(props);
    this.state = { userInputPage: this.props.page };
  }

  static defaultProps: PickOptional = {
    className: '',
    isDisabled: false,
    isCompact: false,
    lastPage: 0,
    firstPage: 0,
    pagesTitle: '',
    pagesTitlePlural: '',
    toLastPageAriaLabel: 'Go to last page',
    toNextPageAriaLabel: 'Go to next page',
    toFirstPageAriaLabel: 'Go to first page',
    toPreviousPageAriaLabel: 'Go to previous page',
    currPageAriaLabel: 'Current page',
    paginationAriaLabel: 'Pagination',
    ofWord: 'of',
    onNextClick: () => undefined as any,
    onPreviousClick: () => undefined as any,
    onFirstClick: () => undefined as any,
    onLastClick: () => undefined as any,
    onPageInput: () => undefined as any
  };

  private static parseInteger(input: React.ReactText, lastPage: number): number {
    // eslint-disable-next-line radix
    let inputPage = Number.parseInt(input as string, 10);
    if (!Number.isNaN(inputPage)) {
      inputPage = inputPage > lastPage ? lastPage : inputPage;
      inputPage = inputPage < 1 ? 1 : inputPage;
    }
    return inputPage;
  }

  private onChange(event: React.FormEvent, lastPage: number): void {
    const inputPage = Navigation.parseInteger(event.currentTarget.value, lastPage);
    this.setState({ userInputPage: Number.isNaN(inputPage as number) ? event.currentTarget.value : inputPage });
  }

  private onKeyDown(
    event: React.KeyboardEvent,
    page: number | string,
    lastPage: number,
    onPageInput: (event: React.SyntheticEvent, page: number) => void
  ): void {
    const allowedKeys = [
      'Tab',
      'Backspace',
      'Delete',
      'ArrowLeft',
      'ArrowRight',
      'Home',
      'End',
      'ArrowUp',
      'ArrowDown'
    ];
    if (event.key === KeyTypes.Enter) {
      const inputPage = Navigation.parseInteger(this.state.userInputPage, lastPage) as number;
      onPageInput(event, Number.isNaN(inputPage) ? (page as number) : inputPage);
      this.handleNewPage(event, Number.isNaN(inputPage) ? (page as number) : inputPage);
    } else if (!/^\d*$/.test(event.key) && !allowedKeys.includes(event.key)) {
      event.preventDefault();
    }
  }

  handleNewPage = (_evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => {
    const { perPage, onSetPage } = this.props;
    const startIdx = (newPage - 1) * perPage;
    const endIdx = newPage * perPage;
    return onSetPage(_evt, newPage, perPage, startIdx, endIdx);
  };

  componentDidUpdate(lastState: NavigationProps) {
    if (
      this.props.page !== lastState.page &&
      this.props.page <= this.props.lastPage &&
      this.state.userInputPage !== this.props.page
    ) {
      this.setState({ userInputPage: this.props.page });
    }
  }

  render() {
    const {
      page,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      perPage,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      onSetPage,
      isDisabled,
      itemCount,
      lastPage,
      firstPage,
      pagesTitle,
      pagesTitlePlural,
      toLastPageAriaLabel,
      toNextPageAriaLabel,
      toFirstPageAriaLabel,
      toPreviousPageAriaLabel,
      currPageAriaLabel,
      paginationAriaLabel,
      ofWord,
      onNextClick,
      onPreviousClick,
      onFirstClick,
      onLastClick,
      onPageInput,
      className,
      isCompact,
      ...props
    } = this.props;
    const { userInputPage } = this.state;
    return (
      
    );
  }
}

export { Navigation };




© 2015 - 2024 Weber Informatics LLC | Privacy Policy