Skip to content

Commit fc461a1

Browse files
committed
Add offset props that set offset distance between menu and its anchor element
1 parent c9f8d47 commit fc461a1

File tree

8 files changed

+80
-42
lines changed

8 files changed

+80
-42
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@szhsin/react-menu",
3-
"version": "0.10.3",
3+
"version": "0.10.4",
44
"description": "React menu components",
55
"author": "Zheng Song",
66
"license": "MIT",

src/components/ControlledMenu.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import PropTypes from 'prop-types';
33
import {
44
menuPropTypesBase,
55
menuDefaultPropsBase,
6+
offsetPropTypes,
7+
offsetDefaultProps,
68
FocusPositions
79
} from '../utils';
810
import { useMenuList } from './useMenuList';
@@ -22,6 +24,8 @@ export const ControlledMenu = React.memo(function ControlledMenu({
2224
isOpen,
2325
isMounted,
2426
menuItemFocus,
27+
offsetX,
28+
offsetY,
2529
children,
2630
onClick,
2731
onClose,
@@ -39,7 +43,9 @@ export const ControlledMenu = React.memo(function ControlledMenu({
3943
direction,
4044
isOpen,
4145
isMounted,
42-
menuItemFocus
46+
menuItemFocus,
47+
offsetX,
48+
offsetY
4349
},
4450
id,
4551
animation,
@@ -51,6 +57,7 @@ export const ControlledMenu = React.memo(function ControlledMenu({
5157

5258
ControlledMenu.propTypes = {
5359
...menuPropTypesBase,
60+
...offsetPropTypes,
5461
anchorPoint: PropTypes.exact({
5562
x: PropTypes.number,
5663
y: PropTypes.number
@@ -66,6 +73,7 @@ ControlledMenu.propTypes = {
6673

6774
ControlledMenu.defaultProps = {
6875
...menuDefaultPropsBase,
76+
...offsetDefaultProps,
6977
isMounted: true,
7078
menuItemFocus: { position: FocusPositions.INITIAL }
7179
};

src/components/Menu.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {
44
safeCall,
55
menuPropTypesBase,
66
menuDefaultPropsBase,
7+
offsetPropTypes,
8+
offsetDefaultProps,
79
Keys,
810
FocusPositions,
911
useMenuChange,
@@ -23,6 +25,8 @@ export const Menu = React.memo(function Menu({
2325
align,
2426
direction,
2527
menuButton,
28+
offsetX,
29+
offsetY,
2630
children,
2731
onClick,
2832
onChange }) {
@@ -97,7 +101,9 @@ export const Menu = React.memo(function Menu({
97101
direction,
98102
isOpen,
99103
isMounted,
100-
menuItemFocus
104+
menuItemFocus,
105+
offsetX,
106+
offsetY
101107
},
102108
id,
103109
animation,
@@ -117,6 +123,7 @@ export const Menu = React.memo(function Menu({
117123

118124
Menu.propTypes = {
119125
...menuPropTypesBase,
126+
...offsetPropTypes,
120127
keepMounted: PropTypes.bool,
121128
menuButton: PropTypes.oneOfType([
122129
PropTypes.element,
@@ -127,5 +134,6 @@ Menu.propTypes = {
127134

128135
Menu.defaultProps = {
129136
...menuDefaultPropsBase,
137+
...offsetDefaultProps,
130138
keepMounted: true
131139
};

src/components/MenuList.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export const MenuList = defineName(React.memo(function MenuList({
3636
isMounted,
3737
isDisabled,
3838
menuItemFocus,
39+
offsetX,
40+
offsetY,
3941
children,
4042
onKeyDown,
4143
onAnimationEnd,
@@ -286,12 +288,12 @@ export const MenuList = defineName(React.memo(function MenuList({
286288
} = positionHelpers();
287289

288290
const anchorRect = anchorRef.current.getBoundingClientRect();
289-
const placeLeftX = anchorRect.left - containerRect.left - menuRect.width;
290-
const placeRightX = anchorRect.right - containerRect.left;
291-
const placeLeftorRightY = anchorRect.top - containerRect.top;
291+
const placeLeftX = anchorRect.left - containerRect.left - menuRect.width - offsetX;
292+
const placeRightX = anchorRect.right - containerRect.left + offsetX;
293+
const placeLeftorRightY = anchorRect.top - containerRect.top + offsetY;
292294

293-
const placeTopY = anchorRect.top - containerRect.top - menuRect.height;
294-
const placeBottomY = anchorRect.bottom - containerRect.top;
295+
const placeTopY = anchorRect.top - containerRect.top - menuRect.height - offsetY;
296+
const placeBottomY = anchorRect.bottom - containerRect.top + offsetY;
295297
let placeToporBottomX;
296298
if (align === 'end') {
297299
placeToporBottomX = anchorRect.right - containerRect.left - menuRect.width;
@@ -301,6 +303,7 @@ export const MenuList = defineName(React.memo(function MenuList({
301303
} else {
302304
placeToporBottomX = anchorRect.left - containerRect.left;
303305
}
306+
placeToporBottomX += offsetX;
304307

305308
let newPosition, x, y;
306309
let computedDirection = direction;

src/components/SubMenu.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
bem,
77
flatStyles,
88
stylePropTypes,
9+
offsetPropTypes,
10+
offsetDefaultProps,
911
menuClass,
1012
subMenuClass,
1113
menuItemClass,
@@ -31,6 +33,8 @@ export const SubMenu = defineName(React.memo(function SubMenu({
3133
keepMounted,
3234
label,
3335
index,
36+
offsetX,
37+
offsetY,
3438
children,
3539
onChange }) {
3640

@@ -175,7 +179,9 @@ export const SubMenu = defineName(React.memo(function SubMenu({
175179
isOpen={isOpen}
176180
isMounted={isMounted}
177181
isDisabled={isDisabled}
178-
menuItemFocus={menuItemFocus}>
182+
menuItemFocus={menuItemFocus}
183+
offsetX={offsetX}
184+
offsetY={offsetY}>
179185
{children}
180186
</MenuList>
181187
</li>
@@ -184,6 +190,7 @@ export const SubMenu = defineName(React.memo(function SubMenu({
184190

185191
SubMenu.propTypes = {
186192
...stylePropTypes,
193+
...offsetPropTypes,
187194
'aria-label': PropTypes.string,
188195
menuClassName: PropTypes.oneOfType([
189196
PropTypes.string,
@@ -204,5 +211,6 @@ SubMenu.propTypes = {
204211
};
205212

206213
SubMenu.defaultProps = {
214+
...offsetDefaultProps,
207215
keepMounted: true
208216
};

src/utils/constants.js

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react';
2-
import PropTypes from 'prop-types';
32

43
export const menuContainerClass = 'rc-menu-container';
54
export const menuClass = 'rc-menu';
@@ -43,35 +42,3 @@ export const CloseReason = Object.freeze({
4342
'CANCEL': 'cancel',
4443
'BLUR': 'blur'
4544
});
46-
47-
export const stylePropTypes = {
48-
className: PropTypes.oneOfType([
49-
PropTypes.string,
50-
PropTypes.func
51-
]),
52-
styles: PropTypes.oneOfType([
53-
PropTypes.object,
54-
PropTypes.func
55-
]),
56-
};
57-
58-
export const menuPropTypesBase = {
59-
...stylePropTypes,
60-
'aria-label': PropTypes.string,
61-
id: PropTypes.oneOfType([
62-
PropTypes.string,
63-
PropTypes.number
64-
]),
65-
animation: PropTypes.bool,
66-
debugging: PropTypes.bool,
67-
align: PropTypes.oneOf(['start', 'center', 'end']),
68-
direction: PropTypes.oneOf(['left', 'right', 'top', 'bottom']),
69-
children: PropTypes.node.isRequired,
70-
onClick: PropTypes.func
71-
};
72-
73-
export const menuDefaultPropsBase = {
74-
animation: true,
75-
align: 'start',
76-
direction: 'bottom'
77-
};

src/utils/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './constants';
2+
export * from './propTypes';
23
export * from './utils';
34
export * from './useActiveState';
45
export * from './useItemState';

src/utils/propTypes.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import PropTypes from 'prop-types';
2+
3+
export const stylePropTypes = {
4+
className: PropTypes.oneOfType([
5+
PropTypes.string,
6+
PropTypes.func
7+
]),
8+
styles: PropTypes.oneOfType([
9+
PropTypes.object,
10+
PropTypes.func
11+
]),
12+
};
13+
14+
export const menuPropTypesBase = {
15+
...stylePropTypes,
16+
'aria-label': PropTypes.string,
17+
id: PropTypes.oneOfType([
18+
PropTypes.string,
19+
PropTypes.number
20+
]),
21+
animation: PropTypes.bool,
22+
debugging: PropTypes.bool,
23+
align: PropTypes.oneOf(['start', 'center', 'end']),
24+
direction: PropTypes.oneOf(['left', 'right', 'top', 'bottom']),
25+
children: PropTypes.node.isRequired,
26+
onClick: PropTypes.func
27+
};
28+
29+
export const menuDefaultPropsBase = {
30+
animation: true,
31+
align: 'start',
32+
direction: 'bottom'
33+
};
34+
35+
export const offsetPropTypes = {
36+
offsetX: PropTypes.number,
37+
offsetY: PropTypes.number
38+
}
39+
40+
export const offsetDefaultProps = {
41+
offsetX: 0,
42+
offsetY: 0
43+
}

0 commit comments

Comments
 (0)