fix: Implement TopNavigation breakpoints in CSS
Description
This PR switches from JavaScript-based breakpoints to CSS container queries for TopNavigation, making its appearance consistent when rendered with SSR. I've added Sass mixins for this purpose that can be reused across other components to replace the useBreakpoints hook.
I've opted to use container queries rather than media queries for backward compatibility's sake, since useBreakpoints checks container size rather than viewport size. However, this introduces a complication: To use container queries, we need to add container-type: inline-size to the TopNavigation element's styles.
I noticed that adding container-type: inline-size causes overflowing content to get clipped in Safari due to a longstanding bug in that browser. [Update 4/5: After updating to Safari 18.4 on my Mac, I no longer see the bug, so it looks like Apple just fixed this.] To address that, I've enabled expandToViewport to render utility dropdowns in a portal. I've also added position: relative and z-index: 1 to the TopNavigation styles to give it a stacking context, which appears to help with the issue. However, there is still a possibility that users who are rendering their own dropdowns in the TopNavigation (e.g. by using an Autosuggest searchbox) without expandToViewport may see issues in older versions of Safari where the dropdown is rendered behind other content with a higher z-index. I would suggest calling this out in the release notes and recommending the use of expandToViewport for dropdowns in TopNavigation.
Once this change is merged, I'd love to start applying this same change to other components that use useBreakpoints. Container queries are supported in all modern browsers.
Fixes #3337
How has this been tested?
I've run this change locally, eyeballed it at different breakpoints, and clicked various controls to ensure that they're visible. I'm open to ideas for testing the breakpoint behavior more thoroughly.
Review checklist
The following items are to be evaluated by the author(s) and the reviewer(s).
Correctness
- Changes include appropriate documentation updates.
-
Changes are backward-compatible if not indicated, see
CONTRIBUTING.md. -
Changes do not include unsupported browser features, see
CONTRIBUTING.md. - Changes were manually tested for accessibility, see accessibility guidelines.
Security
-
If the code handles URLs: all URLs are validated through the
checkSafeUrlfunction.
Testing
- Changes are covered with new/existing unit tests?
- Changes are covered with new/existing integration tests?
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Hello @TrevorBurnham,
Thanks for contributing the fix!
Our team is taking a look and running internal screenshot tests and manual tests.
Could you please fix the failing unit tests? P.S. the "Measure bundle size" action is expected to fail, please ignore it.
@pan-kot Sure thing. I've pushed a fix for the unit tests: 51e8d78
Codecov Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 97.16%. Comparing base (59b27e4) to head (15d4318).
:warning: Report is 1 commits behind head on main.
Additional details and impacted files
@@ Coverage Diff @@
## main #3371 +/- ##
==========================================
- Coverage 97.17% 97.16% -0.01%
==========================================
Files 856 856
Lines 25241 25226 -15
Branches 8939 8932 -7
==========================================
- Hits 24527 24512 -15
Misses 665 665
Partials 49 49
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
- :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
@TrevorBurnham, thanks for addressing the tests! Please also take a look at test coverage.
Also, there is a small regression: the right hand size padding became smaller, see attachments:
Expected:
Actual:
Thanks! Can you give me instructions for viewing the component before/after? What I've been doing is running npm run build and then running a project against the built components directory, but some of the styles seem to be lost in that process (possibly because the "visual refresh" flag doesn't work).
Thanks! Can you give me instructions for viewing the component before/after? What I've been doing is running
npm run buildand then running a project against the built components directory, but some of the styles seem to be lost in that process (possibly because the "visual refresh" flag doesn't work).
The npm run build should be fine: you can build the mainline and then your commit, and compare the differences. The ./pages/lib folder should contain the static assets for the dev pages.
I've updated the PR branch to fix the visual inconsistencies and improve code coverage.
One call-out: Previously TopNavigation passed a prop called offsetRight to the ButtonTrigger for utility menu dropdowns, then added styles based on the .offset-right-* class. Since the offsetRight value depended on the breakpoint in JavaScript, that approach doesn't work; there needs to be a CSS selector that can be used in the TopNavigation styles to reference the ButtonTrigger element. So I added a prop called internalClass to allow a classname to be passed through. Let me know if there's a better way to do this.
I've rebased this branch and made the following changes:
- Added
position: relativeandz-index: 1to theTopNavigationto work around a Safari bug where overflow content from containers withcontainer-type: inline-sizecan be incorrectly rendered behind other elements, causing clipping. I've updated the PR description with more details about this bug, which I think is the most serious potential issue with this change. - Renamed
internalClassNameto justclassNameand added an explanatory comment re: feedback. - Reduced unnecessary test changes and comments re: feedback.
@pan-kot I've rebased and updated this branch.