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

Allow locking of EuiNavDrawer in the expanded state #2247

Merged
merged 16 commits into from
Aug 22, 2019

Conversation

cchaos
Copy link
Contributor

@cchaos cchaos commented Aug 22, 2019

Based on these mocks by @ryankeairns

The EuiNavDrawer now includes a locking icon in the expand button to allow the user to keep the nav drawer open, pushing the body contents instead of overlaying.

A couple of notes:

  • The flyout (second drawer) will still always overlay
  • We restrict the locking ability to wider screens where there's enough room to accommodate both the nav drawer and the body content

Questions: @ryankeairns

  • Currently clicking on the "Collapse" portion of the toggle will also unlock the drawer. Is this expected?
  • Do you think the collapse toggle should look any different when in the locked state? If a user has this locked open for like 90% of the time, that button seems a bit prominent.

Checklist

  • Checked in dark mode
  • Checked in mobile
  • Checked in IE11 and Firefox
  • Props have proper autodocs
  • [ ] Added documentation examples
  • [ ] Added or updated jest tests
  • [ ] Checked for breaking changes and labeled appropriately
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

@ryankeairns
Copy link
Contributor

tenor-57417519

@ryankeairns
Copy link
Contributor

ryankeairns commented Aug 22, 2019

@cchaos to answer your two questions...

(both of these answers are influenced by the hope we can push this along quickly for 7.4)

  1. That was my expectation, yes. I think that if you are deliberately clicking 'Collapse' then it is a safe assumption/expectation that the lock would be undone.
  2. I agree it looks a little heavy visually but having just tried this out - and presuming it will often be used on larger screens - it seems to be far enough out of sight that it didn't make my eye wander down into the corner. Being fixed, the shadow feels essential for scrolling/stuff going under the button, but some other small short-term tweaks could be to lighten up that shadow perhaps? Transparency or some form of hiding feel not great on the surface... My personal opinion is to leave it as-is, live with it for a while, and see how it feels. If it becomes a distraction then let's revisit it as a follow-up task and explore alternative visual and interaction designs.

Seem reasonable? This keeps us moving forward and gives us some time to try it on for size.

@myasonik
Copy link
Contributor

@cchaos I'm not able to tab to that bottom section... Do you know what's going on?
Kapture 2019-08-22 at 18 06 57

Copy link
Contributor

@ryankeairns ryankeairns left a comment

Choose a reason for hiding this comment

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

👍 LGTM. The visual and interaction design look and work as expected across all breakpoints!

As noted in my previous comment, we could explore some additional tweaks to the Collapse button, but I think those are good follow-up tasks which take into account new feedback. As it stands, the change introduced here feels very minimal to the user (basically the addition of an action button) yet provides an impactful enhancement. This buys us some time for exploration which would be beneficial in this situation as the changes may involve more robust interactions based upon state.

@ryankeairns
Copy link
Contributor

@myasonik It looks like the tab order is placing the footer button after the user profile button (in the header) / before the first link in the drawer.

@myasonik
Copy link
Contributor

Also noticed a console error:

Warning: Failed prop type: The prop `onChange` is marked as required in `EuiSwitch`, but its value is `undefined`.
    in EuiSwitch

From context_menu_example.js:16

@myasonik
Copy link
Contributor

Oh yup, good find @ryankeairns

Seems like a very weird tab order. Is that something we can address now @cchaos or should we log it for later?

More critically:
Also seems like it's missing a focus state? And after pressing it (via keyboard) focus is lost and reverts to the body. Can it stay on the button?

@ryankeairns
Copy link
Contributor

Mentioning this issue for context; it's from when we initially released the Nav Drawer. There are some known issues with focus trap that were captured here: #1712

@cchaos
Copy link
Contributor Author

cchaos commented Aug 22, 2019

Regarding the tab-order of the expand button, visually, it doesn't make sense, agreed. However, I had intentionally put the expand button first so that users who are using the keyboard to navigate, can get to it quicker and expand the drawer before they need to tab through all the items, then expand to see the options.

Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

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

I can't leave a comment on the line, so, on 198ish isCollapsed and isLocked need to be unpacked from ...rest so they don't get placed on the div (causes a warning).

I could be mistaken, but Dave mentioned something about localStorage when using this in Kibana. Is the intent to keep locked preference in localStorage? If so, we'll need to provide a callback so that external state can be updated on local state changes.

@@ -36,6 +70,16 @@ export class EuiNavDrawer extends Component {
}, 150);
};

collapseButtonClick = () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Need to remove the resize event listener in this function, also. Otherwise window resizing continues

@cchaos
Copy link
Contributor Author

cchaos commented Aug 22, 2019

@ryankeairns

  1. but some other small short-term tweaks could be to lighten up that shadow perhaps?

Yes, I think that would be really helpful. Even just at all states. I think it's a bit heavy for it's location compared to the EuiHeader.

@cchaos
Copy link
Contributor Author

cchaos commented Aug 22, 2019

@myasonik

Also noticed a console error: ... from context_menu_example.js:16

Yep, but that wasn't changed in this PR.

@cchaos
Copy link
Contributor Author

cchaos commented Aug 22, 2019

@thompsongl

If so, we'll need to provide a callback so that external state can be updated on local state changes.

Best way to do that?

Unpack isCollapsed, isLocked
Remove resize listener on collapse
@thompsongl
Copy link
Contributor

Add a prop onIsLockedUpdate that accepts a function (signature like, (isLocked: boolean) => void). And then call that function whenever setState updates isLocked

@cchaos
Copy link
Contributor Author

cchaos commented Aug 22, 2019

Added callback:

window.addEventListener('resize', this.functionToCallOnWindowResize);
}

this.props.onIsLockedUpdate(!this.state.isLocked);
Copy link
Contributor

Choose a reason for hiding this comment

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

It's possible for this.props.onIsLockedUpdate to be undefined, so check before calling it (and when it's called in collapseButtonClick)

@cchaos cchaos requested a review from thompsongl August 22, 2019 18:19
Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

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

Interaction looks good 👍

@cjcenizal
Copy link
Contributor

cjcenizal commented Aug 22, 2019

Tested this locally and it's fantastic! Thank you for making this change. I experienced a couple friction points in the UX I wanted to raise for your consideration.

Revealing the lock button on hover

In general, I've noticed our components and UIs try not to reveal content on-hover, and I think we've made that decision consciously in the past. Any reason not to keep the lock button visible? It seems like hiding it is an accessibility issue for people using the keyboard to navigate because there is no clear destination to navigate to until you're already there. What do you think @myasonik ?

Lock icon meaning

The lock is used elsewhere in Kibana's UI to represent a "reserved", "protected", or otherwise uneditable state. I'm worried that we might be overloading it with meaning if we use it here in this way. How about a pin icon instead?

image

Forgotten expanded state

I love the way the nav collapses on narrower screens. Nice detail which improves the UX. But can we make it expand again once the user makes their window wider? Put another way, can the nav "remember" if I clicked the lock button and re-apply that state when the screen width can support it?

@ryankeairns
Copy link
Contributor

@cjcenizal regarding the icon: we have plans to use the pin in the nav for users to 'pin' apps to the top of the list, likewise with stars, thus the use of the lock in this case.

Regarding the forgotten expanded state: Could this be handled on the Kibana/consuming app side? Something like if localStorage.navIsLocked is 'on' then add the navIsLocked class ?

@cjcenizal
Copy link
Contributor

we have plans to use the pin in the nav for users to 'pin' apps to the top of the list, likewise with stars, thus the use of the lock in this case.

Thanks for the explanation! It does sound to me like the meaning of the pin in this case is a lot closer to the expand/collapse lock button than the lock icon in the screenshot I shared (the user is "pinning" items in place and "pinning" the drawer in place), but I'll let you make the final call on that.

Re forgotten state, I would expect the responsive behavior to be either wholly controlled by the component or to be wholly controlled by the owner. Currently, it behaves as if it only controls responsive behavior if the window is shrinking but it doesn't control it if the window is expanding. It might be simplest if the owner is responsible for implementing the responsive behavior entirely. This way state only comes from one place, so it's easier to understand and define the behavior we want.

@cchaos
Copy link
Contributor Author

cchaos commented Aug 22, 2019

@cjcenizal We had discussed the responsive handling and had previously decided that it should be "remembered" by the consumer not the component. However, I'm now seeing the limitation of that in which the consumer would then also need to continually pass the locally stored state on resize. I think we can it to remember on resize, however, if it seems like it's more complicated, we may have to punt to second PR so that we can at least get this inital functionality in for FF.

As for the hovering icon, we're using this pattern for all of the nav list items. This isn't a new convention as we also use it in tables for actions.

@cchaos
Copy link
Contributor Author

cchaos commented Aug 22, 2019

There are a lot of edge cases to remembering that locked state the way we handle re-use of the collapse functions no matter the width of the browser. When we had talked about this functionality, we considered the fact that most users aren't changing their browser size so much to make locking the nav again a nuisance. Therefore I'm inclined to punt that functionality for now.

Copy link
Contributor

@snide snide left a comment

Choose a reason for hiding this comment

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

Punt is OK. Let's merge so we're safe for feature freeze. Edge case is likely only to be noticed by people developing Kibana (who resize into small sizes for testing). Agree it's nice to have, so we should fit it in later.

Want to make sure we're not holding up the line with this one.

@cchaos cchaos merged commit 59fc1a1 into elastic:master Aug 22, 2019
@cchaos cchaos deleted the pin-nav-drawer branch August 22, 2019 22:54
thompsongl pushed a commit to thompsongl/eui that referenced this pull request Sep 10, 2019
* Added a locked state of EuiNavDrawer
* Auto-collapses at smaller window sizes
* Collapse all when collapse button is clicked and hide extra action button on smaller screens
* Fix passing classname to extra action
* Allow passing `isLocked` as prop
* Added is `onIsLockedUpdate` callback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants