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

va-pagination: add resize listener to adapt to mobile devices and zoomed layouts #1476

Open
wants to merge 34 commits into
base: main
Choose a base branch
from

Conversation

1Copenut
Copy link
Contributor

@1Copenut 1Copenut commented Feb 3, 2025

Chromatic

https://tpierce-2199-bug-va-pagination--65a6e2ed2314f7b8f98609d8.chromatic.com


Configuring this pull request

  • Link to any related issues in the description so they can be cross-referenced.
  • Add the appropriate version patch label (major, minor, patch, or ignore-for-release).
    • See How to choose a version number for guidance.
    • Use ignore-for-release if files haven't been changed in a component library package. (ie. only Storybook files)
  • DST Only: Increment the /packages/core version number if this will be the last PR merged before a release.
  • Complete all sections below.
  • Delete this section once complete

Description

Closes department-of-veterans-affairs/vets-design-system-documentation#2199.

This PR adds a resizeObserver to the va-pagination component to update the number of pagination links on smaller device viewports and zoomed browser windows.

QA Checklist

  • Component maintains 1:1 parity with design mocks
  • Text is consistent with what's been provided in the mocks
  • Component behaves as expected across breakpoints
  • Accessibility expert has signed off on code changes (if applicable. If not applicable provide reason why)
  • Designer has signed off on changes (if applicable. If not applicable provide reason why)
  • Tab order and focus state work as expected
  • Changes have been tested against screen readers (if applicable. If not applicable provide reason why)
  • New components are covered by e2e tests; updates to existing components are covered by existing test suite
  • Changes have been tested in vets-website using Verdaccio (if applicable. If not applicable provide reason why)

Screenshots

These are screenshots from a local test on vets-website having published the components on Verdaccio (local registry).

Small screen
Screenshot 2025-02-03 124633


Medium screen
Screenshot 2025-02-03 124710


Large screen
Screenshot 2025-02-03 124737

Acceptance criteria

  • QA checklist has been completed
  • Screenshots have been attached that cover desktop and mobile screens

Definition of done

  • Documentation has been updated, if applicable
  • A link has been provided to the originating GitHub issue (or connected to it via ZenHub)

* Updated Storybook instances to five as default maxPageListLength.
* Added tests for mobile display and mobile axe check.
* Added comment for mobile testing device.
@1Copenut 1Copenut self-assigned this Feb 3, 2025
@1Copenut 1Copenut added bug Something isn't working minor For a minor Semantic Version change labels Feb 3, 2025
Copy link
Contributor Author

@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.

Added a few comments to help clarify some of my refactoring decisions.

Comment on lines +520 to +524
{this.renderPreviousButton(arrowClasses, previousAriaLabel)}
{this.renderFirstPage(itemClasses, ellipsisClasses)}
{this.renderMiddlePages(ariaLabelSuffix, itemClasses)}
{this.renderLastPage(ellipsisClasses, itemClasses)}
{this.renderNextPageButton(arrowClasses, nextAriaLabel)}
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 re-architected these into private functions so we could separate the business logic from the render() method. I felt it made the "view layer" easier to read and co-located each piece of the pagination. If there's a better way to render these than individual functions, LMK!

// The smallest breakpoint can show at most 6 pages, including ellipses
if (isMobileViewport) maxPageListLengthState = SHOW_ALL_PAGES;

// Use cases
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 lightly refactored the pageNumbers() function to use if, else if, else logic. I explored using a switch case but didn't feel it was going to scale with multiple props needed to derive the final arrays.

previousAriaLabel: string,
): JSX.Element {
// Skip rendering if the viewport is too narrow to show Previous button
if (this.isMobileViewport) return null;
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 flipped the logic on these new UI render functions. If a condition exists that means this piece of pagination should not be rendered, I returned early using guard clauses. This helped me focus the return statements on the exact markup we wanted.

@1Copenut 1Copenut marked this pull request as ready for review February 10, 2025 20:02
@1Copenut 1Copenut requested a review from a team as a code owner February 10, 2025 20:02
@1Copenut
Copy link
Contributor Author

I tested the change with NVDA, JAWS, and ZoomText on Win11, using Chrome, Firefox, and Edge. Also did basic testing with MS Voice Access to confirm Next, Previous, page numbers clicked as expected.

@jamigibbs jamigibbs removed the bug Something isn't working label Feb 11, 2025
@jamigibbs jamigibbs changed the title [Bug] Add resize listener to va-pagination to adapt to mobile devices and zoomed layouts va-pagination: add resize listener to adapt to mobile devices and zoomed layouts Feb 11, 2025
@@ -55,3 +56,9 @@ button {
transition: all 0.3s ease-in-out;
transition-property: color, background-color;
}

@container (max-width: 640px) { // Variables won't compile. Matching TSX file for now.
Copy link
Contributor

Choose a reason for hiding this comment

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

// Variables won't compile. Matching TSX file for now.

What does this mean?

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 having quite a time passing the USWDS $tablet variable into this container query. I tried var(--tablet) and $tablet and #${tablet} but they either wouldn't render the CSS rule at all, or failed during compilation. Happy to change it if there's something I'm missing.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's really interesting 🤔 I wonder if that's a Stencil limitation? Thanks for explaining!

Do you mind just mentioning in the comment that the value is for the --tablet variable/property?

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 think it's a limitation in Sass. I found this article Want CSS variables in media query declarations? Try this! that digs into the specifics of Sass variables in media and container queries. I'll update the comment explaining the issue.

/**
* =========================================
* End pagination render functions
* =========================================
Copy link
Contributor

@jamigibbs jamigibbs Feb 11, 2025

Choose a reason for hiding this comment

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

Nit: I'm personally not a fan of adding these large comment blocks as waypoints for code sections (here and on line 301). Function names should already be identifying what they're for and it seems like they do. I don't think the design system team has code style guidelines yet but I don't see these types of comment blocks in any other components either.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not a problem, I'll take them out in just a short.

Copy link
Contributor

@jamigibbs jamigibbs left a comment

Choose a reason for hiding this comment

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

Can you double check the unbounded states behavior? If do the following steps for this unbounded middle example, it seems like I can get to a point where I can't click further than page 5. It doesn't seem like the current Storybook example does that.

Screenshot 2025-02-11 at 1 41 55 PM

@1Copenut
Copy link
Contributor Author

Can you double check the unbounded states behavior?

Yes, that looks like a hole in the new logic I introduced. I'll look into it later this afternoon and into tomorrow morning.

@1Copenut 1Copenut requested review from jamigibbs and Andrew565 March 5, 2025 22:27
@1Copenut
Copy link
Contributor Author

1Copenut commented Mar 5, 2025

@jamigibbs & @Andrew565 I'm finally back with an update to this PR. I added a significant amount of logic to the pageNumbers() method to account for more use cases and maxPagetListLength prop set to 6, 8, and 10. I also added logic to the resize observer to decide if we're on a small or slightly less small mobile screen. I was having trouble with the middle numbers and two ellipses at small screen size, so it felt like the best way forward.

I've been testing in Storybook for a couple of days and all of the examples do what I expected, and testing a bunch of variants too. Currently testing in vets-website locally as much as one can with mocked data.

LMK if the added logic needs split or refactored. Thank you!

@1Copenut
Copy link
Contributor Author

1Copenut commented Mar 6, 2025

Some screenshots from localhost testing on Your VA Payment History:

400% zoom at 1280px

Screenshot 2025-03-06 092258


300% zoom at 1280px

Screenshot 2025-03-06 093329


250% zoom at 1280px

Screenshot 2025-03-06 093345

Copy link
Contributor

@jamigibbs jamigibbs left a comment

Choose a reason for hiding this comment

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

@1Copenut Thank you so much for this massive effort! I left a few super minor comments and all of the testing looks pretty good on my end too except one thing I want to check in about.

The USWDS behavior guidelines says:

The component features a maximum of seven slots.

But it looks like now there are more than that. Would that be fairly straight forward to get back in alignment in this PR?

* The number has been reduced from 7 to 6 to show all more consistently
* on small screens and zoomed in browser windows.
*/
SHOW_ALL_PAGES: number = 6;
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this comment make sense in the long run? Should this be reverted back to the original comment?

If the page total is less than or equal to this limit, show all pages.


/**
* Mobile viewport width chosen based on USWDS "mobile-lg" spacing unit.
* See https://designsystem.digital.gov/design-tokens/spacing-units/
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we would prefer this to reference VADS which also uses the same named/value mobile-lg token: https://design.va.gov/foundation/breakpoints

This can be updated in a few different places.


private handlePageSelect = (page, eventID) => {
/**
* Tabllet viewport width chosen based on USWDS "tablet" spacing unit.
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: Tabllet

return makeArray(1, totalPages);
}
} else if (SHOW_ALL_PAGES < totalPages && totalPages <= maxPageListLength) {
console.log('Use case 2');
Copy link
Contributor

Choose a reason for hiding this comment

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

cleanup console.logs in a few different places

@1Copenut
Copy link
Contributor Author

1Copenut commented Mar 6, 2025

@jamigibbs I appreciate the quick review and comments, thank you. I'll remove the errant console statements and mis-spellings in a quick push and focus on getting the total count back in line with production examples (7 or fewer). Will ping you after I have those updates in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
minor For a minor Semantic Version change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pagination doesn't fit on the 320px screen size in Storybook
3 participants