Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiPagination] Added first/last buttons for compressed and allowing for indeterminate pageCount #5362

Merged
merged 28 commits into from
Dec 3, 2021

Conversation

cchaos
Copy link
Contributor

@cchaos cchaos commented Nov 8, 2021

Don't look at the commit summaries, they're inaccurate with the end result 😆

This one got away from me a bit, which meant doing a bit of refactor of the component itself. I'll highlight the actual changes:

Added "First page" and "Last page" arrow buttons when compressed=true

I also removed the click handlers the numbers completely to just rely on the arrow buttons for navigation and the numbers for indicating current page.

Screen.Recording.2021-11-08.at.06.41.03.PM.mp4

This also fixes the situation where users could never get back to the first page easily because the "first / 1" button was replaced with the current page.

Before

Screen.Recording.2021-11-08.at.06.42.07.PM.mp4

Added responsive prop that changes the mobile view to compressed and is customizable

Before, the simplicity in mobile views was ok, but I think it lacked context. So I removed the custom Sass mixins and just created a responsive prop (with the same breakpoints as before) and forced to the compressed view if responsive is anything but `false.

image

Handle situation where pageCount=0 as indeterminate

Fixes #4506

This meant generally hiding all the numbered buttons and relying solely on the arrow buttons to navigate. In order to simplify the activePage count, I determined that negative indexes start from the end. So when pageCount=0 and the user clicks the "Last page" button, it will return -1.

Screen.Recording.2021-11-08.at.06.37.14.PM.mp4

Added doubleArrowLeft, doubleArrowRight, arrowStart, arrowEnd to EuiIcon

These didn't exist yet in order to create the first/last buttons. I also updated the regular arrow versions to the slightly fatter version we've been using in Figma.

Screen Shot 2021-12-02 at 14 58 40 PM

Screen Shot 2021-12-02 at 14 58 46 PM

Update: I replaced the double arrows below with the new ones above, but kept the double arrows in for any future use cases.

Screen Shot 2021-11-08 at 18 44 27 PM

Screen Shot 2021-11-08 at 18 44 34 PM

Checklist

  • Check against all themes for compatibility in both light and dark modes
  • Checked in mobile
  • Checked in Chrome, Safari, Edge, and Firefox
  • Props have proper autodocs and playground toggles
  • Added documentation
  • Checked Code Sandbox works for any docs examples
  • Added or updated jest and cypress tests
  • [ ] Checked for breaking changes and labeled appropriately
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

Copy link
Contributor Author

@cchaos cchaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm keeping this in draft because I want to add some guidelines based on this comment #4506 (comment) but the component work should be reviewable at this point.

Comment on lines 51 to 57
const label = useEuiI18n(
'euiPaginationButtonArrow.previousPage',
({ page }) => `${toSentenceCase(type)} page${page ? `, ${page}` : ''}`,
{
page: labelModifier,
}
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to be clever here and interpolate the type into the i18n, but I'm not sure this is going to work properly. I'm open to suggestions to fix.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably makes the most sense to be verbose and have four distinct labels, one for each type. In any case the token name will need to be updated to match (euiPaginationButtonArrow.previousPage is only correct sometimes)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I just seem to constantly run into the "Hooks can be conditional" issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe do:

const labels = {
  first: useEuiI18n(...),
  previous: useEuiI18n(...),
  next: useEuiI18n(...),
  last: useEuiI18n(...)
}

const label = labels[type];

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to calculate those on every button mount when they'll each only use one?

Copy link
Contributor Author

@cchaos cchaos Nov 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I did that method anyway, just for the type part: 043654f

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

cchaos added 3 commits November 11, 2021 10:50
…nation

# Conflicts:
#	CHANGELOG.md
#	src/components/icon/__snapshots__/icon.test.tsx.snap
@cchaos
Copy link
Contributor Author

cchaos commented Nov 11, 2021

I've decided to push off the Guidelines to a follow up PR because it may require some work to the EuiTablePagination component as well. So I'm opening this PR up for review now.

@cchaos cchaos marked this pull request as ready for review November 11, 2021 16:48
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

@thompsongl
Copy link
Contributor

So when pageCount=0 and the user clicks the "Last page" button, it will return -1.

This makes sense, but is this the intended result if you continue changing the pagination?

Screen Shot 2021-11-17 at 10 01 40 AM

Screen Shot 2021-11-17 at 10 03 48 AM

activePage continues using -1 and decrements from there. This is probably understandable for devs implementing the resulting ES query, but I'm not sure it makes sense to show the user a negative number.

@cchaos
Copy link
Contributor Author

cchaos commented Nov 17, 2021

but I'm not sure it makes sense to show the user a negative number.

I had thought about that too, but honestly, I think it's better to indicate something about their current state in the pagination than nothing.

@cchaos
Copy link
Contributor Author

cchaos commented Nov 23, 2021

Woot! I've pushed the final SR-only wrapper. Can you take one last look once that builds to make sure it all still gets read out properly? It also adds that <span> you had with all the aria- attributes. I wasn't sure if that's still needed or not. d96e254

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

@elizabetdev
Copy link
Contributor

elizabetdev commented Nov 23, 2021

@cchaos it's looking good!

I found just a few small issues in Firefox (94.0.2) and I have one design suggestion. I tested in Chrome, Safari, Edge, and Firefox.

Firefox issues

Focus rings now is being cut in Firefox.
focus-ring@2x

The hover styles are not taking effect in Firefox.

hover@2x

First and last page icon

I did a quick research on other pagination components and most of them are using a similar icon to the ones you added: doubleArrowLeft and doubleArrowRight. But IMO the following type of icon represents better first and last pages. What do you think?

pagination@2x

@cchaos
Copy link
Contributor Author

cchaos commented Nov 23, 2021

Thanks @miukimiu . I'm working on those Firefox fixes.

In general, first/last buttons aren't great but it's the only way to quickly get to the first page when there isn't numbering. I also agree that in isolation, the icon that you showed is more representative of going to the beginning/end. The problem I see with them is that they harder to distinguish between themselves and the single arrow previous/next icons.

If you'd like to continue exploring options for the icon, I'm happy to wait to finalize this PR next week.

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

// The compressed version already should the activePage with pageCount, so it just needs `Page`
// The other types will append the whole string with total pageCount or `collection`
const accessiblePageCount = compressed
? pageLabel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compressed true statement renders "Page" in the compressed SR-only block. Could we add a dynamic element like activePage + 1 so screen readers pick up the change and announce a page number?

This is my only additional comment. The code is working really well in VO and I was able to traverse each pagination example easily and clearly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would that not duplicate the active page number and make the readout "Page 1, 1 of 5"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading my comment again, I don't think I was as clear as I'd hoped.

The compressed accessiblePageCount text is just "Page" right now. For consistency, I'd like to make it render "Page 1 of 5". We should be able to pull that off with string interpolation like you're using in other SR-only blocks.

! pagination.tsx#289

const pageLabel = useEuiI18n('euiPagination.page', 'Page');

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mostly understood what you meant. But I'm wondering if that will duplicate what the screen-reader reads out since the actual visible text is 1 of 5 but the screen-reader-only text would be Page 1 of 5. So would it not then read both? So you'd hear "Page 1 of 5. 1 of 5"?

Copy link
Contributor

@1Copenut 1Copenut Nov 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'm following you now. Yes and no. The visual text would be a repeat, but that change wouldn't be announced when users press Next, Previous, First, or Last buttons. Screen reader users will just hear the SR-only live region we're adding until they arrow through the visual text. If they're moving by TAB or other shortcut keys, they may never settle on the visual text. It could feel a little heavy, but I'm inclined to err on the side of redundancy over brevity in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok gotcha, I'll just remove the compressed specific logic and have it read out the same as all the others.

Copy link
Contributor

@1Copenut 1Copenut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! I had just one comment about the compressed view's SR-only message, and I'm ready to approve.

@cchaos cchaos requested a review from 1Copenut December 2, 2021 16:57
@elizabetdev
Copy link
Contributor

Before, the simplicity in mobile views was ok, but I think it lacked context

@cchaos I agree with this and I prefer having more context. But just noticed that now in mobile the pagination is taking too much space. Is there anything we can do to reduce the size? Maybe in mobile instead of saying "Rows per page" just "Rows"?

Mobile pagination@2x

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

Copy link
Contributor

@elizabetdev elizabetdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @cchaos for fixing the Firefox issues. LGTM! 🎉

Because we also have to rethink the pagination for #4458 (smarter pagination display on skinny screens/containers) I'm ok if you ignore my latest comment.

Copy link
Contributor

@1Copenut 1Copenut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 LGTM!

@cchaos
Copy link
Contributor Author

cchaos commented Dec 2, 2021

Thanks @1Copenut and @miukimiu !!! I've pushed the new icons:
Screen Shot 2021-12-02 at 14 49 30 PM

As for the mobile issues with the table pagination that contains the Rows per page selector, I will be dealing with that in a follow up I've already started to help in general with that pattern.

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5362/

@cchaos
Copy link
Contributor Author

cchaos commented Dec 3, 2021

I'd love to get a final eng check on this PR before I merge 🙏

Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes LGTM!

@cchaos
Copy link
Contributor Author

cchaos commented Dec 3, 2021

Merging! Thanks everyone for the reviews 💟

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[EuiPagination] add a variation with next/previous buttons only
5 participants