-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
fix(sidenav): sidenavmenu stays open when in rail #3626
fix(sidenav): sidenavmenu stays open when in rail #3626
Conversation
Deploy preview for the-carbon-components ready! Built with commit 94d6a0d https://deploy-preview-3626--the-carbon-components.netlify.com |
Deploy preview for carbon-elements ready! Built with commit 94d6a0d |
Deploy preview for carbon-components-react ready! Built with commit 94d6a0d https://deploy-preview-3626--carbon-components-react.netlify.com |
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.
LTGM! 🎉
Seems like this PR has broken functionality for other versions of the UI Shell: https://deploy-preview-3626--carbon-components-react.netlify.com/?path=/story/ui-shell--header-base-w-navigation-actions-and-sidenav I'm not able to open any of the left nav menu's |
Good spot @tw15egan I will look into that now |
And since this was the main bug blocking the Rail version from being displayed, should we go ahead and add a story for the Rails version in now that it seems to be working properly? Or do we want to wait until keyboard functionality is worked in as well (#3529)? cc @jnm2377 and @aledavila for your opinions |
@tw15egan yea I had suggested we display now if it does work. Since the other one is an enhancement |
Fixes issue found with existing behaviour
Hi all, As requested, I have added the story in to the storybook. I don’t know if I need to include the build of the storybook or not in the PR, but have not for now. If it is needed, let me know. As for the issue @tw15egan found, I have guarded the passing of expansion state so it only does this if Just one note on why this happened originally too. I was expecting the |
Hi thanks @matthew-chirgwin Its looking good so far. But there is still an issue the menu now doesn't pin open on click of the header menu. There are 2 ways that the rail should open. On hover of the side nav or on click of the header menu and it should remain open. I believe it was working before. |
The story looks great, and it seems like you've got open on focus behavior sorted. Awesome! I see that the other stories are now working as intended. I'm also noticing the issue @aledavila pointed out. In addition, would it be possible to add the active state to the closed menu item, like so: Looking good so far, and thanks for all the work you've put into this 👍 |
Update storybook
Hey @aledavila @tw15egan . Thanks for the feedback. I've added the required props/callbacks in to allow the rails story to work as you expected (I had removed them for local testing and did not put them back). That has just been added to the branch now ready for review. I also had a (quick) look at adding the active state when collapsed. With the change as I have it, an active menu will keep the styling even if I interact with another item: Is it a must have for this issue, or worth a follow on issue? |
Thanks for the update. It seems that now the submenus don't open on hover. But if you click them open and then click the header menu the ones you clicked to open are open. So it seems to be passing in the open prop but it doesn't actually open on hover. |
@asudoh @joshblack Is this really the prefered method instead of using context? I don't see how mapping over the children is any more explicit than context, the only difference is it's less flexible and transparent for developers. |
Propagate-prop-to-child pattern is one we have employed since the inception of the codebase. It has "unintentional override of props" problem and I personally have considered of switching it to render-props, but I haven't figured out a pattern that works for every affected components (e.g. tabs). That said, using propagate-prop-to-child pattern here is fine to me. |
@asudoh a major issue you had with context is that the passing of props wasn't explicit to developers. How is this pattern any different? |
Propagate-prop-to-child doesn't break the deterministic behavior of components upon props. |
If I understand things correctly, what @asudoh is referring to is that using In your proposal, Vince, were you suggesting having a default provider embedded in our components or would it noop with the default arguments passed into |
Hi all - just as an FYI, I am on vacation this week, which means I won’t be able to make any immediate changes to this PR. I don’t object to updating to use context if that is the preference - I went with props as I started the change from the |
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.
The latest code LGTM 👍 - Thanks @matthew-chirgwin!
66e07ff
to
0d177f7
Compare
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.
The latest update makes sense, just one thing - Thanks @matthew-chirgwin!
onMouseEnter={() => handleToggle(true)} | ||
onMouseLeave={() => handleToggle(false)}> | ||
{children} | ||
onMouseEnter={() => handleToggle({}, true)} |
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.
Any reason not passing along the event?
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.
Hi @asudoh good point - as it was returning true
/false
before, it should continue to do so. I will change this to onMouseEnter={() => handleToggle(true, true)}
and onMouseLeave={() => handleToggle(false, false)}
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.
as it was returning
true
/false
before, it should continue to do so.
Right. An interesting part is (as you may have noticed) that the old code didn't have one-arg interface. And other callers of handleToggle()
passes along the raw event. So I was wondering if we could do:
onMouseEnter={() => handleToggle({}, true)} | |
onMouseEnter={event => handleToggle(event, true)} |
Address review comment
335d4e8
to
0a034e8
Compare
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.
This looks really great! Thanks for making all these changes/improvements👍
wrt @designertyler comment above. It looks like the active
|
add/fix isActive check in menu
ea2c5c4
to
ee67d78
Compare
Hi @designertyler @jnm2377 /all - as it turns out, the was a small bug in the |
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.
Looks good to me!
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.
Just small things to ensure that it's no lost in the pile of conversation - Thank you for all the updates @matthew-chirgwin!
onMouseEnter={() => handleToggle(true)} | ||
onMouseLeave={() => handleToggle(false)}> | ||
{children} | ||
onMouseEnter={() => handleToggle(true, true)} |
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.
onMouseEnter={() => handleToggle(true, true)} | |
onMouseEnter={event => handleToggle(event, true)} |
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.
@asudoh - before my changes, handleToggle
was called here with just true as the only argument. I can change it to whatever the event is as you suggest, but if someone downstream passes the onToggle
property to the SideNav
and expects the bool value, would that not be a breaking change for them?
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.
Thank you for putting your thoughts on this and elaborating it @matthew-chirgwin! I now see your point (I missed it, tricked by argument name), and I now think the best is keeping handleToggle()
call intact - Meaning, call with one arg.
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.
Hi @asudoh - the only issue with moving to one argument is the effect that would then have on how I changed handleToggle
to handle this case (lines 48-50). That change could be pushed into its own function, but would that add any value?
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.
Just leaving a note, though this is merged already; I think the best approach is making handleToggle()
obvious that the first arg is optional and and the second arg becomes the first arg when the caller doesn't specify the first arg.
onMouseLeave={() => handleToggle(false)}> | ||
{children} | ||
onMouseEnter={() => handleToggle(true, true)} | ||
onMouseLeave={() => handleToggle(false, false)}> |
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.
onMouseLeave={() => handleToggle(false, false)}> | |
onMouseLeave={event => handleToggle(event, false)}> |
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.
@asudoh - same here as my comment above
Update for reviewers: we decided we'll be going with context based components for UI shell. However, given that we need to update more than just the rails functionality to use context (this is a bigger effort than the scope of this PR), we are merging this in as-is and will update to context in a separate PR. |
Issue for context: #3797 |
Closes #3527
The
SideNavMenu
component when used in aSideNav
(usingisRail
property) maintains its space for its child items when the rail is collapsed if selected. This change adds a property to determine if theSideNav
is open, and in the case of theSideNavMenu
, change state if it was open/closed when the rail is open/closed.Changelog
Changed
isSideNavExpanded
property to child components of the SideNavgDSFP
logic toSideNavMenu
to detect and handle this caseTesting / Reviewing
Unit tests have been added to check on the
gDSFP
logic toSideNavMenu
to make sure this issue could not return . If more testing is required please let me know and Ill update the PR.