-
Notifications
You must be signed in to change notification settings - Fork 536
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
UnderlineNav v2 item can enter a selected non-current state #2865
Comments
@broccolinisoup do you want to take a look at this one? |
I'm on it! |
Just noting a possibly related issue with the same component. Sometimes, not all items will be shown during a render (e.g. the last element might be missing), however when resizing the page the last element(s) will also be rendered. To be specific, it is not that the element is being shown in an extensible menu, it is that sometimes the last elements are not rendered at all. |
@pveierland That is strange. "Sometimes" issues are tricky! - Thanks so much for letting us know. I plan to look into this issue next week and hopefully resolve 🤞🏻 |
Just adding a screenshot of how it appeared now. In this case the final item "Settings" was not added at all, while "Resources" and "Versions" are shown in an extension menu, even though there is available layout space for all items without using the dropdown. Resizing the page makes all items render: |
@pveierland Thanks! I'll certainly look into why some items is missing in the first render but I should also add that in the first render, even though there is enough space on the viewport, the last two item being in the overflow menu is expected (in SSR). Because the placement of the elements is entirely dependent on the viewport width and when the HTML is rendered in the server, it doesn't know the viewport size so it renders as you just described. Let me know if I misunderstand anything about the behaviour you described! I feel like an item is being missing might be to do with the server render as well 🤔 |
@broccolinisoup That does explain the behavior of the first render. The "Settings" entry also requires a flag which is not set during the server render, and will only render when this flag is set on the client-side. However, wouldn't the component be re-rendered automatically after hydration and when these props have changed? |
Hey @pveierland 👋🏻 Sorry for the late response!
Thanks for letting me know about that!
The component is re-rendered when the props are changed as well as when the viewport size is changed. However, regarding re-rendering automatically after hydration, I would say it is a option that needs to be chosen carefully as it will most likely cause a layout shift. To my understanding and experience, the behaviour of a component both on the client and the server should be intentional. They can be different and that is completely fine as long as it is intentional by design. This is the case for UnderlineNav. The component relies on viewport size for accurate rendering on the client and for server, the last two item being hiding in the overflow menu in the first load is fine and we don't consider this as a bug. Let us know if you have further questions 🙌🏻 |
@pveierland Regarding the original issue, thank you so much for reporting it again. I have found a few issues related to keeping the selected item visible in SSR and I believe the original issue you mentioned is something to do with it. I'll post my findings here in the next couple of days hopefully and come up with more SSR compatible solution. |
Hi, this is blocking us from moving to My use case is very simple. Basically <UnderlineNav>
{options.map((option) => {
return (
<UnderlineNav.Item
key={href}
aria-current={option.value === currentValue ? 'page' : false}
>{option.value}</UnderlineNav.Item>}
)}
</UnderlineNav> Nothing fancy. <hr />
Change current value:
<button onClick={() => setCurrentValue('linux')}>linux</button>
<button onClick={() => setCurrentValue('mac')}>mac</button>
<button onClick={() => setCurrentValue('windows')}>windows</button> The confusing thing is that the DOM updates. But the styling, the little orange underlining, does not update. Screen.Recording.2023-05-17.at.10.30.32.AM.movHowever, and sorry if it's hard to see in the video, but the bug is that the class name |
Ah! I kinda get it. At least a small clue. <UnderlineNav.Item
key={href}
aria-current={option.value === currentValue ? 'page' : undefined}
href={href}
onClick={(event) => {
onClickChoice(option.value)
}} If I remove that However, I still can't control it from the outside. Screen.Recording.2023-05-17.at.10.41.34.AM.movIn my real final version I'm not going to have those buttons below that call useEffect(() => {
// Focus the 'linux' button if the location hash says so
if (window.location.hash.includes('linux') {
setCurrentValue('linux')
}
}, []) Perhaps I can solve my use-case with useEffect(() => {
// Focus the 'linux' button if the location hash says so
if (window.location.hash.includes('linux') {
document.querySelector('[data-nav="linux"]').click()
}
}, []) but that feels hacky :) |
and obviously wouldn't work because a DOM click will trigger the underlying |
Hi @peterbe 👋🏻 Thanks for your comment, I can confirm now that indeed there is a bug here :) Thank you for taking the time to post reproducible info and screen recordings. I'll be coming here and update the issue once I resolve the problem. Thanks 🙏🏻 |
Hi 👋🏻 Thanks for your patience with me 🙏🏻 I think I got some good progress. I tested the scenarios on a sample SPA and seems like it is working. I still need to work through some styling and some bits and pieces - because I went ahead and did some refactoring - however I believe it is at a good stage to test out. I pushed a PR with my changes and every PR publishes a canary build #3361 - would that be possible to test out the |
I have not had a chance to fully try it yet. |
@broccolinisoup Good news! Your canary build solves the problem. |
@peterbe Great news! Thanks so much for testing and giving me feedback. I will work on the final details and getting the PR ready for review, hopefully we will release it soon! |
Uh oh! @echarles, the image you shared is missing helpful alt text. Check #2865 (comment). Alt text is an invisible description that helps screen readers describe images to blind or low-vision users. If you are using markdown to display images, add your alt text inside the brackets of the markdown image. Learn more about alt text at Basic writing and formatting syntax: images on GitHub Docs. |
Description
During use of the UnderlineNav v2 component, it appears that the
UnderlineNav.Item
can end up showing as being selected, while its proparia-current
is set toundefined
orfalse
.This may be caused by a race condition, as it seems to be triggered when moving between pages quickly / when rendering has not been completed.
Example of "Meta" not being selected and "Inputs" being selected:
Props showing that "Meta" item has
aria-current
set topage
and should be selected:Props showing that "Inputs" item has
aria-current
set tofalse
and should not be selected:Testing performed using React Primer v35.19.0 and Next.js v13.1.6 with wrapper component as detailed in: https://primer.style/react/drafts/UnderlineNav2#with-nextjs
Steps to reproduce
UnderlineNav.Item
).UnderlineNav.Item
will end up in the state where it is shown visually as being selected, while havingaria-current
set toundefined
orfalse
.Expected behavior would be for the
aria-current
and visual state of theUnderlineNav.Item
to always be in sync.Version
v35.19.0
Browser
Chrome, Firefox
The text was updated successfully, but these errors were encountered: