Skip to content

Commit ec550fd

Browse files
committed
feat(cdk/menu): not to close on outside click
this commit adds new input in menu trigger which allows users to disable closing menu on outside clicks fixes #29072
1 parent 371446a commit ec550fd

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

src/cdk/menu/context-menu-trigger.spec.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ describe('CdkContextMenuTrigger', () => {
143143
fixture.detectChanges();
144144
expect(getContextMenu()).toBeDefined();
145145
});
146+
147+
it('should stay open with disable close on outside click', () => {
148+
fixture.componentInstance.shoudCloseOnOutsideClicks = true;
149+
openContextMenu();
150+
expect(getContextMenu()).toBeDefined();
151+
152+
fixture.nativeElement.querySelector('#other').click();
153+
fixture.detectChanges();
154+
expect(getContextMenu()).toBeDefined();
155+
});
146156
});
147157

148158
describe('nested context menu triggers', () => {
@@ -442,7 +452,8 @@ describe('CdkContextMenuTrigger', () => {
442452

443453
@Component({
444454
template: `
445-
<div [cdkContextMenuTriggerFor]="context"></div>
455+
<div [cdkContextMenuTriggerFor]="context"
456+
[cdkContextMenuDisableCloseOnOutsideClick]="shoudCloseOnOutsideClicks"></div>
446457
<div id="other"></div>
447458
448459
<ng-template #context>
@@ -459,6 +470,8 @@ class SimpleContextMenu {
459470
@ViewChild(CdkMenu, {read: ElementRef}) nativeMenu?: ElementRef<HTMLElement>;
460471

461472
@ViewChildren(CdkMenu) menus: QueryList<CdkMenu>;
473+
474+
shoudCloseOnOutsideClicks = false;
462475
}
463476

464477
@Component({

src/cdk/menu/context-menu-trigger.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ export class CdkContextMenuTrigger extends CdkMenuTriggerBase implements OnDestr
9696
/** Whether the context menu is disabled. */
9797
@Input({alias: 'cdkContextMenuDisabled', transform: booleanAttribute}) disabled: boolean = false;
9898

99+
/** Whether on clicking outside of menu should close it */
100+
@Input({alias: 'cdkContextMenuDisableCloseOnOutsideClick', transform: booleanAttribute})
101+
disableCloseOnOutsideClick: boolean = false;
102+
99103
constructor() {
100104
super();
101105
this._setMenuStackCloseListener();
@@ -210,7 +214,10 @@ export class CdkContextMenuTrigger extends CdkMenuTriggerBase implements OnDestr
210214

211215
outsideClicks.pipe(takeUntil(this.stopOutsideClicksListener)).subscribe(event => {
212216
if (!this.isElementInsideMenuStack(_getEventTarget(event)!)) {
213-
this.menuStack.closeAll();
217+
// We do not want to close menu if user does not want to on outside clicks.
218+
if (!this.disableCloseOnOutsideClick) {
219+
this.menuStack.closeAll();
220+
}
214221
}
215222
});
216223
}

tools/public_api_guard/cdk/menu.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,16 @@ export const CDK_MENU: InjectionToken<Menu>;
3535
export class CdkContextMenuTrigger extends CdkMenuTriggerBase implements OnDestroy {
3636
constructor();
3737
close(): void;
38+
disableCloseOnOutsideClick: boolean;
3839
disabled: boolean;
3940
// (undocumented)
41+
static ngAcceptInputType_disableCloseOnOutsideClick: unknown;
42+
// (undocumented)
4043
static ngAcceptInputType_disabled: unknown;
4144
open(coordinates: ContextMenuCoordinates): void;
4245
_openOnContextMenu(event: MouseEvent): void;
4346
// (undocumented)
44-
static ɵdir: i0.ɵɵDirectiveDeclaration<CdkContextMenuTrigger, "[cdkContextMenuTriggerFor]", ["cdkContextMenuTriggerFor"], { "menuTemplateRef": { "alias": "cdkContextMenuTriggerFor"; "required": false; }; "menuPosition": { "alias": "cdkContextMenuPosition"; "required": false; }; "menuData": { "alias": "cdkContextMenuTriggerData"; "required": false; }; "disabled": { "alias": "cdkContextMenuDisabled"; "required": false; }; }, { "opened": "cdkContextMenuOpened"; "closed": "cdkContextMenuClosed"; }, never, never, true, never>;
47+
static ɵdir: i0.ɵɵDirectiveDeclaration<CdkContextMenuTrigger, "[cdkContextMenuTriggerFor]", ["cdkContextMenuTriggerFor"], { "menuTemplateRef": { "alias": "cdkContextMenuTriggerFor"; "required": false; }; "menuPosition": { "alias": "cdkContextMenuPosition"; "required": false; }; "menuData": { "alias": "cdkContextMenuTriggerData"; "required": false; }; "disabled": { "alias": "cdkContextMenuDisabled"; "required": false; }; "disableCloseOnOutsideClick": { "alias": "cdkContextMenuDisableCloseOnOutsideClick"; "required": false; }; }, { "opened": "cdkContextMenuOpened"; "closed": "cdkContextMenuClosed"; "outsideClicked": "cdkContextMenuOutsideClicked"; }, never, never, true, never>;
4548
// (undocumented)
4649
static ɵfac: i0.ɵɵFactoryDeclaration<CdkContextMenuTrigger, never>;
4750
}

0 commit comments

Comments
 (0)