{"version":3,"file":"Pagination.cjs","sources":["../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { useMemo, type JSX } from 'react';\n\nimport { t } from '@grafana/i18n';\n\nimport { useStyles2 } from '../../themes/ThemeContext';\nimport { Button, ButtonVariant } from '../Button/Button';\nimport { Icon } from '../Icon/Icon';\n\nexport interface Props {\n  /** The current page index being shown. */\n  currentPage: number;\n  /** Number of total pages. */\n  numberOfPages: number;\n  /** Callback function for fetching the selected page.  */\n  onNavigate: (toPage: number) => void;\n  /** When set to true and the pagination result is only one page it will not render the pagination at all. */\n  hideWhenSinglePage?: boolean;\n  /** Small version only shows the current page and the navigation buttons. */\n  showSmallVersion?: boolean;\n  className?: string;\n  /** If we are using cursor based pagination, disable next page button when we have no cursor */\n  hasNextPage?: boolean;\n}\n\n/**\n * Component used for rendering a page selector below paginated content.\n *\n * https://developers.grafana.com/ui/latest/index.html?path=/docs/navigation-pagination--docs\n */\nexport const Pagination = ({\n  currentPage,\n  numberOfPages,\n  onNavigate,\n  hideWhenSinglePage,\n  showSmallVersion,\n  className,\n  hasNextPage,\n}: Props) => {\n  const styles = useStyles2(getStyles);\n  const pageLengthToCondense = showSmallVersion ? 1 : 8;\n\n  const pageButtons = useMemo(() => {\n    const pages = [...new Array(numberOfPages).keys()];\n\n    const condensePages = numberOfPages > pageLengthToCondense;\n    const getListItem = (page: number, variant: 'primary' | 'secondary') => (\n      <li key={page} className={styles.item}>\n        <Button size=\"sm\" variant={variant} onClick={() => onNavigate(page)}>\n          {page}\n        </Button>\n      </li>\n    );\n\n    return pages.reduce<JSX.Element[]>((pagesToRender, pageIndex) => {\n      const page = pageIndex + 1;\n      const variant: ButtonVariant = page === currentPage ? 'primary' : 'secondary';\n\n      // The indexes at which to start and stop condensing pages\n      const lowerBoundIndex = pageLengthToCondense;\n      const upperBoundIndex = numberOfPages - pageLengthToCondense + 1;\n      // When the indexes overlap one another this number is negative\n      const differenceOfBounds = upperBoundIndex - lowerBoundIndex;\n\n      const isFirstOrLastPage = page === 1 || page === numberOfPages;\n      // This handles when the lowerBoundIndex < currentPage < upperBoundIndex\n      const currentPageIsBetweenBounds =\n        differenceOfBounds > -1 && currentPage >= lowerBoundIndex && currentPage <= upperBoundIndex;\n\n      // Show ellipsis after that many pages\n      const ellipsisOffset = showSmallVersion ? 1 : 3;\n\n      // The offset to show more pages when currentPageIsBetweenBounds\n      const pageOffset = showSmallVersion ? 0 : 2;\n\n      if (condensePages) {\n        if (\n          isFirstOrLastPage ||\n          (currentPage < lowerBoundIndex && page < lowerBoundIndex) ||\n          (differenceOfBounds >= 0 && currentPage > upperBoundIndex && page > upperBoundIndex) ||\n          (differenceOfBounds < 0 && currentPage >= lowerBoundIndex && page > upperBoundIndex) ||\n          (currentPageIsBetweenBounds && page >= currentPage - pageOffset && page <= currentPage + pageOffset)\n        ) {\n          // Renders a button for the page\n          pagesToRender.push(getListItem(page, variant));\n        } else if (\n          (page === lowerBoundIndex && currentPage < lowerBoundIndex) ||\n          (page === upperBoundIndex && currentPage > upperBoundIndex) ||\n          (currentPageIsBetweenBounds &&\n            (page === currentPage - ellipsisOffset || page === currentPage + ellipsisOffset))\n        ) {\n          // Renders and ellipsis to represent condensed pages\n          pagesToRender.push(\n            <li key={page} className={styles.item}>\n              <Icon className={styles.ellipsis} name=\"ellipsis-v\" data-testid=\"pagination-ellipsis-icon\" />\n            </li>\n          );\n        }\n      } else {\n        pagesToRender.push(getListItem(page, variant));\n      }\n      return pagesToRender;\n    }, []);\n  }, [currentPage, numberOfPages, onNavigate, pageLengthToCondense, showSmallVersion, styles.ellipsis, styles.item]);\n\n  if (hideWhenSinglePage && numberOfPages <= 1) {\n    return null;\n  }\n\n  const previousPageLabel = t('grafana-ui.pagination.previous-page', 'previous page');\n  const nextPageLabel = t('grafana-ui.pagination.next-page', 'next page');\n\n  return (\n    <div className={cx(styles.container, className)} role=\"navigation\">\n      <ol>\n        <li className={styles.item}>\n          <Button\n            aria-label={previousPageLabel}\n            size=\"sm\"\n            variant=\"secondary\"\n            onClick={() => onNavigate(currentPage - 1)}\n            disabled={currentPage === 1}\n          >\n            <Icon name=\"angle-left\" />\n          </Button>\n        </li>\n        {pageButtons}\n        {pageButtons.length === 0 && <li className={styles.item}>{currentPage}</li>}\n        <li className={styles.item}>\n          <Button\n            aria-label={nextPageLabel}\n            size=\"sm\"\n            variant=\"secondary\"\n            onClick={() => onNavigate(currentPage + 1)}\n            disabled={hasNextPage === false || currentPage === numberOfPages}\n          >\n            <Icon name=\"angle-right\" />\n          </Button>\n        </li>\n      </ol>\n    </div>\n  );\n};\n\nconst getStyles = () => {\n  return {\n    container: css({\n      float: 'right',\n    }),\n    item: css({\n      display: 'inline-block',\n      paddingLeft: '10px',\n      marginBottom: '5px',\n    }),\n    ellipsis: css({\n      transform: 'rotate(90deg)',\n    }),\n  };\n};\n"],"names":["useStyles2","useMemo","jsx","Button","Icon","t","cx","jsxs","css"],"mappings":"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"}