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

fix(cdk-experimental/menu): fix bug preventing keyboard event handling if opened programmatically #20004

Merged
merged 1 commit into from
Jul 21, 2020

Conversation

andy9775
Copy link
Contributor

If a menu is opened programmatically, subsequent keyboard events to close it out are not handled.
This fixes the issue by tracking the open sub-menu regardless of how it was opened up.

@andy9775 andy9775 requested a review from jelbourn as a code owner July 16, 2020 13:45
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jul 16, 2020
detectChanges();

fileMenuNativeItems[0].focus();
dispatchKeyboardEvent(document.activeElement!, 'keydown', TAB);
Copy link
Member

Choose a reason for hiding this comment

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

This could result in test flakes since browsers won't move focus in some cases on the CI (primarily if the window is out of focus). It might be better if you send the event directly to fileMenuNativeItems[0].

item
.getMenuTrigger()!
.closed.pipe(take(1), takeUntil(this._destroyed))
.subscribe(() => (this._openItem = undefined));
Copy link
Member

Choose a reason for hiding this comment

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

Subscribing inside of a subscription is a bit of anti-pattern in rxjs since you can end up with multiple concurrent subscriptions. It might be better if you did this with a switchMap and only subscribed once at the end.

item
.getMenuTrigger()!
.closed.pipe(take(1), takeUntil(this.closed))
.subscribe(() => (this._openItem = undefined));
Copy link
Member

Choose a reason for hiding this comment

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

Same note here about subscribing inside a subscription.

@andy9775 andy9775 force-pushed the cdk-menu-fix-programatic-open branch 2 times, most recently from e2b3c2c to 7e6f75c Compare July 16, 2020 16:33
@@ -207,6 +212,33 @@ export class CdkMenuBar extends CdkMenuGroup implements Menu, AfterContentInit,
return this.orientation === 'horizontal';
}

/**
* Subscribe to the menu trigger's open events in order to track the trigger which opened the menu
* and stop tracking it when the menu is closed closed.

Choose a reason for hiding this comment

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

typo: double 'closed'

.map(item =>
item
.getMenuTrigger()!
.opened.pipe(mapTo(item), takeUntil(merge(this._allItems.changes, this._destroyed)))

Choose a reason for hiding this comment

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

Here too, is it possible to unnest some of these nested operators? I've tended to have odd behavior with this sort of thing. (Should there be a persistent object-level observable merging this._allItems.changes and this._destroyed?)

this._allItems.changes
.pipe(
startWith(this._allItems),
mergeMap((list: QueryList<CdkMenuItem>) =>

Choose a reason for hiding this comment

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

Similar to above comment?

@andy9775 andy9775 force-pushed the cdk-menu-fix-programatic-open branch from 7e6f75c to adf11f3 Compare July 16, 2020 21:08
@andy9775
Copy link
Contributor Author

@crisbeto @teflonwaffles feedback should be addressed.

@andy9775 andy9775 force-pushed the cdk-menu-fix-programatic-open branch from adf11f3 to 39d06ee Compare July 16, 2020 21:31
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

Comment on lines 457 to 461
fixture.debugElement
.queryAll(By.directive(CdkMenuItem))[0]
.injector.get(CdkMenuItem)
.getMenuTrigger()!
.openMenu();
Copy link
Member

Choose a reason for hiding this comment

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

nit: +4 indent for line overflow, so this would be e.g.

Suggested change
fixture.debugElement
.queryAll(By.directive(CdkMenuItem))[0]
.injector.get(CdkMenuItem)
.getMenuTrigger()!
.openMenu();
fixture.debugElement
.queryAll(By.directive(CdkMenuItem))[0]
.injector.get(CdkMenuItem)
.getMenuTrigger()!
.openMenu();

* Subscribe to the menu trigger's open events in order to track the trigger which opened the menu
* and stop tracking it when the menu is closed.
*/
private _subscribeToMenuOpen() {
Copy link
Member

Choose a reason for hiding this comment

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

Not strictly necessary for this PR, but it would be good to cut down on the duplication between menu and menubar here. Maybe just add a TODO for now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, totally agree. Once everything is finalized I think pulling the duplicated logic out into an abstract Menu class is the way to go.

@jelbourn jelbourn added target: patch This PR is targeted for the next patch release lgtm labels Jul 20, 2020
@jelbourn
Copy link
Member

You can add the merge-ready label when ready

…g if opened programmatically

If a menu is opened programmatically, subsequent keyboard events to close it out are not handled.
This fixes the issue by tracking the open sub-menu regardless of how it was opened up.
@andy9775 andy9775 force-pushed the cdk-menu-fix-programatic-open branch from 39d06ee to da11787 Compare July 21, 2020 00:11
@andy9775 andy9775 added the action: merge The PR is ready for merge by the caretaker label Jul 21, 2020
@wagnermaciel wagnermaciel merged commit 7303780 into angular:master Jul 21, 2020
wagnermaciel pushed a commit that referenced this pull request Jul 21, 2020
…g if opened programmatically (#20004)

If a menu is opened programmatically, subsequent keyboard events to close it out are not handled.
This fixes the issue by tracking the open sub-menu regardless of how it was opened up.

(cherry picked from commit 7303780)
@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: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants