Skip to content

Commit e869e36

Browse files
committed
Add rtl prop to the ContextMenu Component
This allows the ContextMenu to render on the left side of the cursor. Useful to RTL directional pages
1 parent 1c976d6 commit e869e36

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

examples/RTLSubMenu.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ export default class RTLSubMenu extends Component {
2323
render() {
2424
return (
2525
<div>
26-
<h3>Right-to-Left Submenu Menu</h3>
26+
<h3>Right-to-Left ContextMenu and Submenu Menu</h3>
2727
<p>This demos usage of Right-to-Left submenus.</p>
2828
<ContextMenuTrigger id={MENU_TYPE} holdToDisplay={1000}>
2929
<div className='well'>right click to see the menu</div>
3030
</ContextMenuTrigger>
3131
<div>
3232
{this.state.logs.map((log, i) => <p key={i}>{log}</p>)}
3333
</div>
34-
<ContextMenu id={MENU_TYPE}>
34+
<ContextMenu id={MENU_TYPE} rtl>
3535
<MenuItem onClick={this.handleClick} data={{ item: 'item 1' }}>Menu Item 1</MenuItem>
3636
<MenuItem onClick={this.handleClick} data={{ item: 'item 2' }}>Menu Item 2</MenuItem>
3737
<SubMenu title='A SubMenu' rtl>

src/ContextMenu.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export default class ContextMenu extends AbstractMenu {
1616
data: PropTypes.object,
1717
className: PropTypes.string,
1818
hideOnLeave: PropTypes.bool,
19+
rtl: PropTypes.bool,
1920
onHide: PropTypes.func,
2021
onMouseLeave: PropTypes.func,
2122
onShow: PropTypes.func,
@@ -26,6 +27,7 @@ export default class ContextMenu extends AbstractMenu {
2627
className: '',
2728
data: {},
2829
hideOnLeave: false,
30+
rtl: false,
2931
onHide() { return null; },
3032
onMouseLeave() { return null; },
3133
onShow() { return null; },
@@ -57,7 +59,9 @@ export default class ContextMenu extends AbstractMenu {
5759
wrapper(() => {
5860
const { x, y } = this.state;
5961

60-
const { top, left } = this.getMenuPosition(x, y);
62+
const { top, left } = this.props.rtl
63+
? this.getRTLMenuPosition(x, y)
64+
: this.getMenuPosition(x, y);
6165

6266
wrapper(() => {
6367
if (!this.menu) return;
@@ -178,6 +182,39 @@ export default class ContextMenu extends AbstractMenu {
178182
return menuStyles;
179183
}
180184

185+
getRTLMenuPosition = (x = 0, y = 0) => {
186+
let menuStyles = {
187+
top: y,
188+
left: x
189+
};
190+
191+
if (!this.menu) return menuStyles;
192+
193+
const { innerWidth, innerHeight } = window;
194+
const rect = this.menu.getBoundingClientRect();
195+
196+
// Try to position the menu on the left side of the cursor
197+
menuStyles.left = x - rect.width;
198+
199+
if (y + rect.height > innerHeight) {
200+
menuStyles.top -= rect.height;
201+
}
202+
203+
if (menuStyles.left < 0) {
204+
menuStyles.left += rect.width;
205+
}
206+
207+
if (menuStyles.top < 0) {
208+
menuStyles.top = rect.height < innerHeight ? (innerHeight - rect.height) / 2 : 0;
209+
}
210+
211+
if (menuStyles.left + rect.width > innerWidth) {
212+
menuStyles.left = rect.width < innerWidth ? (innerWidth - rect.width) / 2 : 0;
213+
}
214+
215+
return menuStyles;
216+
}
217+
181218
menuRef = (c) => {
182219
this.menu = c;
183220
}

tests/__snapshots__/ContextMenu.test.js.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ exports[`ContextMenu tests does not shows when event with incorrect "id" is trig
99
onHide={[Function]}
1010
onMouseLeave={[Function]}
1111
onShow={[Function]}
12+
rtl={false}
1213
style={Object {}}
1314
>
1415
<nav
@@ -37,6 +38,7 @@ exports[`ContextMenu tests does not shows when event with incorrect "id" is trig
3738
onHide={[Function]}
3839
onMouseLeave={[Function]}
3940
onShow={[Function]}
41+
rtl={false}
4042
style={Object {}}
4143
>
4244
<nav
@@ -65,6 +67,7 @@ exports[`ContextMenu tests shows when event with correct "id" is triggered 1`] =
6567
onHide={[Function]}
6668
onMouseLeave={[Function]}
6769
onShow={[Function]}
70+
rtl={false}
6871
style={Object {}}
6972
>
7073
<nav
@@ -93,6 +96,7 @@ exports[`ContextMenu tests shows when event with correct "id" is triggered 2`] =
9396
onHide={[Function]}
9497
onMouseLeave={[Function]}
9598
onShow={[Function]}
99+
rtl={false}
96100
style={Object {}}
97101
>
98102
<nav

0 commit comments

Comments
 (0)