Skip to content

[Pagination] unexpected behavior when setting boundaryCount and siblingCount #24749

Closed

Description

@jhumpohl
  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

1.) When i set the boundaryCount={0} just to show the current page and use the prev and next buttons. The current page is just displayed on the first page or last but isnt displayed when you navigate to any other page.

2.) When i set the boundaryCount={1} and the siblingCount={1} the pages that are shown add up.
a) For example when the current page is on 5 from 10 The shown pages are
< 1 ... 4 [5] 6 ... 10 > thats right.
b) When you are at page 4 it looks like this
< 1 2 3 [4] 5 ... 10 > and should be < 1 ... 3 [4] 5 ...>.
c) When you are at page 1 it looks like this
< [1] 2 3 4 5 ... 10 > and from my opinion should be like this < [1] 2 ... 10 >

Expected Behavior 🤔

1.) Show the current page any time :).

2.) a) is ok how it is
b) should be < 1 ... 3 [4] 5 ...>
c) should be < [1] 2 ... 10 >

Steps to Reproduce 🕹

I used the code Sandbox from the Examples and just changed the Props on the component.

https://codesandbox.io/s/bn7nw
and added the props like described above. For 1) boundaryCount={0} For 2) boundaryCount={1} and the siblingCount={1}

Context 🔦

Its a Navigation for a Responsive Website with Page Results that need Filters,Limits and navigation. Because its for Phones too it needs to be small sometimes.

Your Environment 🌎

`npx @material-ui/envinfo`
  Don't forget to mention which browser you used.
  Output from `npx @material-ui/envinfo` goes here.

Activity

  1. mbrookes commented on Feb 2, 2021

    @mbrookes
    Member

    This is by design, as it keeps the width of the pagination component stable.

  2. added
    scope: paginationChanges related to the pagination.
    not plannedThe problem seems valid, but we don't intend to fix it (won't fix).
    and removed on Feb 2, 2021
  3. oliviertassinari commented on Feb 2, 2021

    @oliviertassinari
    Member

    @mbrookes I agree with point 2), the request is invalid, we should keep pagination width stable. However, on point 1, this

    <Pagination boundaryCount={0} siblingCount={0} count={10} page={page} onChange={handleChange} />

    seems to behave strangely https://codesandbox.io/s/material-demo-forked-2nkvf?file=/demo.js.

  4. oliviertassinari commented on Feb 2, 2021

    @oliviertassinari
    Member

    For instance, on page 7, we get:

    Capture d’écran 2021-02-03 à 00 33 39

    why not the following?

    Capture d’écran 2021-02-03 à 00 37 37

    or even

    Capture d’écran 2021-02-03 à 00 39 07

  5. jhumpohl commented on Feb 3, 2021

    @jhumpohl
    Author

    I dont think the component keeps it width when you go up to a page count above 100 but if this is the reason i can understand point 2). I would maybe had drop the three points to keep the size.

    But at point 1) its the same Reason? If so it makes no sense to me. the current page is much more important than the point or page count. I would had expected a solution like oliviertassinari posted.

    But anyway thx for the quick awnser and support.

  6. oliviertassinari commented on Feb 13, 2021

    @oliviertassinari
    Member

    So, I had a look at the issue. It turns out that we have already fixed most of the issue in v5: https://codesandbox.io/s/material-demo-forked-2nkvf?file=/demo.js.

    Having a second thought about it, I would propose that for:

    <Pagination boundaryCount={0} siblingCount={0} count={10}

    It renders:

    Capture d’écran 2021-02-03 à 00 39 07

    Instead of:

    Capture d’écran 2021-02-03 à 00 37 37

    It allows to have a denser display, the dots don't really add much. I could make it work with this diff:

    index 4f15278cb1..f92c0bf84f 100644
    --- a/packages/material-ui/src/usePagination/usePagination.js
    +++ b/packages/material-ui/src/usePagination/usePagination.js
    @@ -65,33 +65,41 @@ export default function usePagination(props = {}) {
         endPages.length > 0 ? endPages[0] - 2 : count - 1,
       );
    
    -  // Basic list of items to render
    -  // e.g. itemList = ['first', 'previous', 1, 'ellipsis', 4, 5, 6, 'ellipsis', 10, 'next', 'last']
    -  const itemList = [
    -    ...(showFirstButton ? ['first'] : []),
    -    ...(hidePrevButton ? [] : ['previous']),
    -    ...startPages,
    -
    -    // Start ellipsis
    +  // Start ellipsis
    +  const startEllipsis =
         // eslint-disable-next-line no-nested-ternary
    -    ...(siblingsStart > boundaryCount + 2
    +    siblingsStart > boundaryCount + 2
           ? ['start-ellipsis']
           : boundaryCount + 1 < count - boundaryCount
           ? [boundaryCount + 1]
    -      : []),
    -
    -    // Sibling pages
    -    ...range(siblingsStart, siblingsEnd),
    +      : [];
    
    -    // End ellipsis
    +  // End ellipsis
    +  const endEllipsis =
         // eslint-disable-next-line no-nested-ternary
    -    ...(siblingsEnd < count - boundaryCount - 1
    +    siblingsEnd < count - boundaryCount - 1
           ? ['end-ellipsis']
           : count - boundaryCount > boundaryCount
           ? [count - boundaryCount]
    -      : []),
    +      : [];
    
    -    ...endPages,
    +  const body =
    +    boundaryCount === 0 && siblingCount === 0
    +      ? [page]
    +      : [
    +          ...startPages,
    +          ...startEllipsis,
    +          ...range(siblingsStart, siblingsEnd),
    +          ...endEllipsis,
    +          ...endPages,
    +        ];
    +
    +  // Basic list of items to render
    +  // e.g. itemList = ['first', 'previous', 1, 'start-ellipsis', 4, 5, 6, 'end-ellipsis', 10, 'next', 'last']
    +  const itemList = [
    +    ...(showFirstButton ? ['first'] : []),
    +    ...(hidePrevButton ? [] : ['previous']),
    +    ...body,
         ...(hideNextButton ? [] : ['next']),
         ...(showLastButton ? ['last'] : []),
       ];

    Should we move forward with it?

  7. removed
    not plannedThe problem seems valid, but we don't intend to fix it (won't fix).
    on Feb 13, 2021
  8. jhumpohl commented on Feb 15, 2021

    @jhumpohl
    Author

    To me first and last page is more important then the dots. And on small displays you dont really have the space. To me it looks good. The biggest issue was the missing of the current page in the current V4 version.

    Nice job!

  9. fayzzzm commented on Feb 26, 2021

    @fayzzzm
    Contributor

    @oliviertassinari, I know it could be a stupid question from me, but what if the developer passes count float value

    <Pagination count={1.03} />

    and next button won't be disabled due to this line of code

    disabled:
                disabled ||
                (item.indexOf('ellipsis') === -1 &&
                  (item === 'next' || item === 'last' ? page >= count : page <= 1))

    Pagination code link

    What if instead of checking page >= count make page >= parseInt(count) or to parseInt it at the beginning.

  10. oliviertassinari commented on Feb 26, 2021

    @oliviertassinari
    Member

    @fayzzzm What's the link with this issue? I don't think that the core logic should care about float. However, we could introduce a custom integer prop-type, we have a couple of other cases where PropTypes.number isn't ideal. If you want to work on it, contribution welcome 👍

  11. fayzzzm commented on Feb 26, 2021

    @fayzzzm
    Contributor

    Ok, I will create an issue and you can have a look at it. We could discuss props validating after if it's ok?

  12. oliviertassinari commented on Feb 26, 2021

    @oliviertassinari
    Member

    @fayzzzm To be clear, we don't want to support count={1.03}, we want to throw a warning when developers try to us this API (at least, it seems to be what would make the most sense).

  13. fayzzzm commented on Feb 26, 2021

    @fayzzzm
    Contributor
  14. added and removed
    good first issueGreat for first contributions. Enable to learn the contribution process.
    on Jun 30, 2021
  15. added
    ready to takeHelp wanted. Guidance available. There is a high chance the change will be accepted
    on Jul 16, 2021
  16. Boulea7 commented on Aug 12, 2026

    @Boulea7

    I am starting work on the remaining boundaryCount={0} and siblingCount={0} case. I will add a regression test for the compact previous/current/next output described in the maintainer proposal, while leaving other pagination configurations unchanged.

  17. lprnmns commented on Sep 4, 2026

    @lprnmns
    Contributor

    I reproduced the remaining case on current master: boundaryCount={0} with siblingCount={0} still emits start/end ellipses around the current page. I plan to implement the maintainer-proposed special case so the body contains only the current page, with a focused regression test. The August attempt has no linked or open PR after more than three weeks.

  18. Boulea7 commented on Oct 8, 2026

    @Boulea7

    I opened #48954 for the compact-pagination case, including reachability and focus behavior. Linking it here to help coordinate the work and avoid duplicate implementations.

  19. removed
    ready to takeHelp wanted. Guidance available. There is a high chance the change will be accepted
    on Oct 26, 2026
  20. Janpot commented on Oct 26, 2026

    @Janpot
    Member

    We discussed this as a team and decided against #24749 (comment). The ellipses carry useful information and are a separate concept from boundaryCount and siblingCount. An ellipsis means "more pages are hidden here", while those props set how many pages to show around the extremities and the current page. The intended behavior, which is also what Material UI renders today, is the following for count={10} boundaryCount={0} siblingCount={0}:

    page rendered
    1 < [1] 2 … >
    2 < 1 [2] … >
    5 < … [5] … >
    7 < … [7] … >
    9 < … [9] 10 >
    10 < … 9 [10] >

    If you need a denser layout without ellipses, you can filter them out with renderItem:

    <Pagination
      count={10}
      boundaryCount={0}
      siblingCount={0}
      renderItem={(item) =>
        item.type === 'start-ellipsis' || item.type === 'end-ellipsis' ? null : (
          <PaginationItem {...item} />
        )
      } 
    />

    For full control over the markup, use the usePagination hook. If you feel strongly that the ellipses should be removed by default, please open a new issue.

    @lprnmns We think #49090 could meaningfully improve test coverage, so we'd like to adopt it once it's updated to follow this direction.

    @Boulea7 Thanks for picking this up, and sorry the ready to take label sent you down this path. We'll close #48954 for now.

  21. github-actions commented on Oct 26, 2026

    @github-actions
    Contributor

    This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
    Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.


    @jhumpohl Thanks again for creating this issue! If you have a moment, we would love to hear your thoughts on how we handled it with this short feedback form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    scope: paginationChanges related to the pagination.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions