Skip to content

Commit 53f937e

Browse files
Add horizontalAlignment to Menu.open() options (#732)
* add align to menu.IOpenOptions * add align * add test * adds tests and default direction * add docstring * lint * try making test more reliable * lint and update api * use floor instead of round * change align to horizontalAlignment * lint * update docstrings * update api
1 parent 2361102 commit 53f937e

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

packages/widgets/src/menu.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,21 @@ export class Menu extends Widget {
465465
let forceY = options.forceY || false;
466466
const host = options.host ?? null;
467467
const ref = options.ref ?? null;
468+
const horizontalAlignment =
469+
options.horizontalAlignment ??
470+
(document.documentElement.dir === 'rtl' ? 'right' : 'left');
468471

469472
// Open the menu as a root menu.
470-
Private.openRootMenu(this, x, y, forceX, forceY, host, ref);
473+
Private.openRootMenu(
474+
this,
475+
x,
476+
y,
477+
forceX,
478+
forceY,
479+
horizontalAlignment,
480+
host,
481+
ref
482+
);
471483

472484
// Activate the menu to accept keyboard input.
473485
this.activate();
@@ -1009,6 +1021,13 @@ export namespace Menu {
10091021
* menu to be added as the last child of the host.
10101022
*/
10111023
ref?: HTMLElement;
1024+
1025+
/**
1026+
* The alignment of the menu.
1027+
*
1028+
* The default is `'left'` unless the document `dir` attribute is `'rtl'`
1029+
*/
1030+
horizontalAlignment?: 'left' | 'right';
10121031
}
10131032

10141033
/**
@@ -1559,6 +1578,7 @@ namespace Private {
15591578
y: number,
15601579
forceX: boolean,
15611580
forceY: boolean,
1581+
horizontalAlignment: 'left' | 'right',
15621582
host: HTMLElement | null,
15631583
ref: HTMLElement | null
15641584
): void {
@@ -1589,6 +1609,11 @@ namespace Private {
15891609
// Measure the size of the menu.
15901610
let { width, height } = node.getBoundingClientRect();
15911611

1612+
// align the menu to the right of the target if requested or language is RTL
1613+
if (horizontalAlignment === 'right') {
1614+
x -= width;
1615+
}
1616+
15921617
// Adjust the X position of the menu to fit on-screen.
15931618
if (!forceX && x + width > px + cw) {
15941619
x = px + cw - width;

packages/widgets/tests/src/menu.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,30 @@ describe('@lumino/widgets', () => {
604604
);
605605
});
606606

607+
it('should accept horizontalAlignment menu flags', () => {
608+
menu.addItem({ command: 'test' });
609+
menu.open(300, 300, { horizontalAlignment: 'right' });
610+
let { width } = menu.node.getBoundingClientRect();
611+
const expectedX = Math.floor(300 - width);
612+
expect(
613+
menu.node.style.transform.startsWith(`translate(${expectedX}`)
614+
).to.equal(true);
615+
expect(menu.node.style.transform.endsWith('px, 300px)')).to.equal(true);
616+
});
617+
618+
it.only('horizontalAlignment should default to `right` if language direction is `rtl`', () => {
619+
document.documentElement.setAttribute('dir', 'rtl');
620+
menu.addItem({ command: 'test' });
621+
menu.open(300, 300);
622+
let { width } = menu.node.getBoundingClientRect();
623+
const expectedX = Math.floor(300 - width);
624+
expect(
625+
menu.node.style.transform.startsWith(`translate(${expectedX}`)
626+
).to.equal(true);
627+
expect(menu.node.style.transform.endsWith('px, 300px)')).to.equal(true);
628+
document.documentElement.removeAttribute('dir'); // Reset the direction
629+
});
630+
607631
it('should bail if already attached', () => {
608632
menu.addItem({ command: 'test' });
609633
menu.open(10, 10);

review/api/widgets.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@ export namespace Menu {
741741
export interface IOpenOptions {
742742
forceX?: boolean;
743743
forceY?: boolean;
744+
horizontalAlignment?: 'left' | 'right';
744745
host?: HTMLElement;
745746
ref?: HTMLElement;
746747
}

0 commit comments

Comments
 (0)