-
Notifications
You must be signed in to change notification settings - Fork 655
Fix and refactor UnderlineNav to resolve CLS issues and improve performance/code quality
#7506
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
base: main
Are you sure you want to change the base?
Changes from all commits
7b8e794
a0e4f42
604c035
7fc6739
6921a86
1bc03b6
cc8b23b
be8b640
f5b4a72
ff30931
dfda985
ab2806c
588223e
68f2ef1
184ea86
591b5ec
b65d397
e0773f5
8824b2d
399300c
500e706
35735d2
3deb5f9
de7ff00
e01b457
690943a
b06222b
ead0546
82d821e
cc1e347
9d3ba17
ec9462f
b34a523
c1dd8f1
d98c04b
ec2c47c
df15a1e
eef80ba
2aec372
f7a0ec9
d55720d
8fd5b4a
67effbc
1ba092a
247ab9c
dea0dd0
0f8782b
c7abf30
9efdf26
7772123
f818594
eacda5b
4a90231
d57aa24
231f742
3a4e37c
52bf25f
759aafe
d3c41c3
4d8d5e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@primer/react": minor | ||
| --- | ||
|
|
||
| Refactors `UnderlineNav` overflow handling to use CSS-based overflow detection instead of JavaScript width measurements, eliminating layout shift (CLS) issues and improving performance. The overflow menu is now implemented with `ActionMenu`, and item registration uses a descendant registry instead of the `React.Children` API. Consumer-facing changes: items can now be wrapped in fragments or wrapper components; the current item may appear in the overflow menu when the viewport is narrow; and the overflow menu button is right-aligned. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,62 @@ | ||
| .MenuItemContent { | ||
| .UnderlineWrapper { | ||
| /* Progressive enhancement: Detect overflow using scroll-based animations. | ||
| The idiomatic way would be a scroll-state container query but browser support | ||
| is slightly better for animations. */ | ||
| animation: detect-overflow linear; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice progressive enhancement! One thought: between first paint and the first IO callback, overflowing items will be clipped but the "More" button won't be visible yet. Is that flash acceptable, or should we show the button by default and hide it once we confirm nothing overflows?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice progressive enhancement! One thought: between first paint and the first IO callback, overflowing items will be clipped but the "More" button won't be visible yet. Is that flash acceptable, or should we show the button by default and hide it once we confirm nothing overflows?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice progressive enhancement! One thought: between first paint and the first IO callback, overflowing items will be clipped but the "More" button won't be visible yet. Is that flash acceptable, or should we show the button by default and hide it once we confirm nothing overflows? |
||
| animation-timeline: scroll(self block); | ||
|
|
||
| &[data-hide-icons='true'] { | ||
| --UnderlineNav_icons-display: none; | ||
| } | ||
|
|
||
| &[data-has-overflow='true'] { | ||
| --UnderlineNav_moreButton-visibility: visible; | ||
| } | ||
| } | ||
|
|
||
| @keyframes detect-overflow { | ||
| 0%, | ||
| 100% { | ||
| --UnderlineNav_moreButton-visibility: visible; | ||
| --UnderlineNav_icons-display: none; | ||
| } | ||
| } | ||
|
|
||
| .ItemsList [data-component='icon'] { | ||
| display: var(--UnderlineNav_icons-display, inline); | ||
| } | ||
|
|
||
| .MoreButtonContainer { | ||
| display: flex; | ||
| visibility: var(--UnderlineNav_moreButton-visibility, hidden); | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| } | ||
|
|
||
| /* More button styles migrated from styles.ts (was moreBtnStyles) */ | ||
| .OverflowMenuItem [aria-current] { | ||
| position: relative; | ||
|
|
||
| .OverflowMenuItemLabel { | ||
| font-weight: var(--base-text-weight-semibold); | ||
| } | ||
|
|
||
| &::after { | ||
| content: ''; | ||
| width: var(--base-size-2); | ||
| position: absolute; | ||
| inset: var(--base-size-2) auto var(--base-size-2) 0; | ||
| /* stylelint-disable-next-line primer/colors */ | ||
| background: var(--underlineNav-borderColor-active); | ||
| } | ||
| } | ||
iansan5653 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| .MoreButtonDivider { | ||
| display: inline-block; | ||
| border-left: var(--borderWidth-default) solid var(--borderColor-muted); | ||
| width: 0; | ||
| margin-inline: var(--base-size-4); | ||
| height: var(--base-size-24); | ||
| } | ||
|
|
||
| .MoreButton { | ||
| margin: 0; /* reset Safari extra margin */ | ||
| border: 0; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the label of the overflow button to "More items", aligning with this issue for
ActionBar: #7437