diff --git a/packages/widgets/src/menu.ts b/packages/widgets/src/menu.ts index 35b9fd6d5..80ca9e7e8 100644 --- a/packages/widgets/src/menu.ts +++ b/packages/widgets/src/menu.ts @@ -446,6 +446,12 @@ export class Menu extends Widget { * fully fit on the screen. If it will not fit, it will be adjusted * to fit naturally on the screen. * + * The menu will be attached under the `host` element in the DOM + * (or `document.body` if `host` is `null`) and before the `ref` + * element (or as the last child of `host` if `ref` is `null`). + * The menu may be displayed outside of the `host` element + * following the rules of CSS absolute positioning. + * * This is a no-op if the menu is already attached to the DOM. */ open(x: number, y: number, options: Menu.IOpenOptions = {}): void { @@ -457,8 +463,8 @@ export class Menu extends Widget { // Extract the menu options. let forceX = options.forceX || false; let forceY = options.forceY || false; - const host = options.host || null; - const ref = options.ref || null; + const host = options.host ?? null; + const ref = options.ref ?? null; // Open the menu as a root menu. Private.openRootMenu(this, x, y, forceX, forceY, host, ref); diff --git a/packages/widgets/tests/src/menu.spec.ts b/packages/widgets/tests/src/menu.spec.ts index 99cc786ce..2bc7e1809 100644 --- a/packages/widgets/tests/src/menu.spec.ts +++ b/packages/widgets/tests/src/menu.spec.ts @@ -612,7 +612,7 @@ describe('@lumino/widgets', () => { }); it('should insert as last child under document.body by default', () => { - const div = document.body.appendChild(document.createElement('div')) + const div = document.body.appendChild(document.createElement('div')); menu.addItem({ command: 'test' }); menu.open(10, 10); expect(menu.node.parentElement).to.equal(document.body); @@ -621,8 +621,8 @@ describe('@lumino/widgets', () => { }); it('should insert as last child under specified host element', () => { - const div = document.body.appendChild(document.createElement('div')) - const child = div.appendChild(document.createElement('div')) + const div = document.body.appendChild(document.createElement('div')); + const child = div.appendChild(document.createElement('div')); menu.addItem({ command: 'test' }); menu.open(10, 10, { host: div }); expect(menu.node.parentElement).to.equal(div); @@ -631,8 +631,8 @@ describe('@lumino/widgets', () => { }); it('should insert before reference element under document.body', () => { - const div1 = document.body.appendChild(document.createElement('div')) - const div2 = document.body.appendChild(document.createElement('div')) + const div1 = document.body.appendChild(document.createElement('div')); + const div2 = document.body.appendChild(document.createElement('div')); menu.addItem({ command: 'test' }); menu.open(10, 10, { ref: div2 }); expect(menu.node.parentElement).to.equal(document.body); @@ -641,7 +641,7 @@ describe('@lumino/widgets', () => { }); it('should insert before reference element under specified host element', () => { - const div = document.body.appendChild(document.createElement('div')) + const div = document.body.appendChild(document.createElement('div')); const child1 = div.appendChild(document.createElement('div')); const child2 = div.appendChild(document.createElement('div')); menu.open(10, 10, { host: div, ref: child2 }); diff --git a/review/api/widgets.api.md b/review/api/widgets.api.md index 7462b947b..745ba5003 100644 --- a/review/api/widgets.api.md +++ b/review/api/widgets.api.md @@ -741,6 +741,8 @@ export namespace Menu { export interface IOpenOptions { forceX?: boolean; forceY?: boolean; + host?: HTMLElement; + ref?: HTMLElement; } export interface IOptions { commands: CommandRegistry;