Skip to content

refactor(cdk-experimental/menu): refactor MenuStack to ensure submenus are popped off and closed #20006

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

Merged
merged 1 commit into from
Jul 21, 2020

Conversation

andy9775
Copy link
Contributor

When closing a menu from the menu stack this ensures that any sub-menu's are popped off the stack
and closed resulting in a stack which represents the state of the UI.

@andy9775 andy9775 requested a review from jelbourn as a code owner July 16, 2020 13:59
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jul 16, 2020
@andy9775 andy9775 requested a review from teflonwaffles July 16, 2020 14:04
* Pop off the top most MenuStackItem and emit it on the close observable.
* Pop off the top most MenuStackItem and emit it on the close observable if the stack is not
* empty. If `lastElement` is provided it will pop off until this element (inclusive). If
* `lastElement` is not in the stack, it will pop off the topmost element only.

Choose a reason for hiding this comment

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

This seems like somewhat odd behavior for such a function -- if anything, I would expect it to keep popping until the end of the stack if it doesn't encounter the specified lastElement.

It's not wrong per se, but it feels counterintuitive. Is there a way to achieve the intended overall behavior without relying on this behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you're referring to what happens when lastElement is not provided that was just a fallback behaviour decision for which under normal circumstances it shouldn't be encountered. I figured that in the edge case where that may occur it would be better to pop off rather than do nothing. I'm flexible to either approach though.

* @param focusNext the event to emit on the `empty` observable if the method call resulted in an
* empty stack. Does not emit if the stack was initially empty.
*/
closeExclusive(lastElement?: MenuStackItem, focusNext?: FocusNext) {

Choose a reason for hiding this comment

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

Hmm, now there are two methods that do the same thing if you don't provide a parameter, but behave differently if you do. Are you sure these two methods definitely need the first parameter to be optional? Also, can you achieve the effect you need with a pair of methods that don't overlap? (Eg. 'closeExclusive() and closeLatest()'.) That way, you might be able to avoid the slightly redundant method implementations.

@andy9775 andy9775 force-pushed the cdk-menu-stack-close-till branch from 84b2561 to 752ffa9 Compare July 17, 2020 18:46
if (menuStackItem) {
this._close.next(menuStackItem);
if (this._elements.length === 0) {
closeInclusive(lastItem: MenuStackItem, focusNext?: FocusNext) {
Copy link
Member

Choose a reason for hiding this comment

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

How about just close for this method (with the closing of all its sub-menus implied) and then either closeChildrenOf or closeSubMenusOf for the other method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. There is already a close observable but I renamed it to closed along with empty to emptied. LMK

expect(menus.length).toBe(3);

menuStack.close.subscribe(item => {
expect(item).toEqual(menus.pop()!);
Copy link
Member

Choose a reason for hiding this comment

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

Why is this non-null assertion (!) necessary here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pop may return undefined and the expect call requires a MenuStackItem. I changed it around though so it's not necessary anymore though which addresses the below comment as well

openAllMenus();
expect(menus.length).toBe(3);

menuStack.close.subscribe(item => {
Copy link
Member

Choose a reason for hiding this comment

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

Having an expect in a subscribe is tricky because you're not guaranteed that the stream will actually emit.


/** Return true if this stack is empty. */
isEmpty() {
return this._elements.length === 0;
Copy link
Member

Choose a reason for hiding this comment

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

optionally could do:

Suggested change
return this._elements.length === 0;
return !!this._elements.length;

@andy9775 andy9775 force-pushed the cdk-menu-stack-close-till branch 2 times, most recently from ffe6f83 to baeda3e Compare July 21, 2020 14:52
@andy9775
Copy link
Contributor Author

@teflonwaffles @jelbourn feedback should be addressed.

…s are popped off and closed

When closing a menu from the menu stack this ensures that any sub-menu's are popped off the stack
and closed resulting in a stack which represents the state of the UI.
@andy9775 andy9775 force-pushed the cdk-menu-stack-close-till branch from baeda3e to c66cd11 Compare July 21, 2020 14:56
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

LGTM

@jelbourn jelbourn added lgtm action: merge The PR is ready for merge by the caretaker target: minor This PR is targeted for the next minor release labels Jul 21, 2020
@wagnermaciel wagnermaciel merged commit ba441d4 into angular:master Jul 21, 2020
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Aug 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants