Skip to content

Commit

Permalink
Add offset props that set offset distance between menu and its anchor…
Browse files Browse the repository at this point in the history
… element
  • Loading branch information
szhsin committed Oct 10, 2020
1 parent c9f8d47 commit fc461a1
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 42 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@szhsin/react-menu",
"version": "0.10.3",
"version": "0.10.4",
"description": "React menu components",
"author": "Zheng Song",
"license": "MIT",
Expand Down
10 changes: 9 additions & 1 deletion src/components/ControlledMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import PropTypes from 'prop-types';
import {
menuPropTypesBase,
menuDefaultPropsBase,
offsetPropTypes,
offsetDefaultProps,
FocusPositions
} from '../utils';
import { useMenuList } from './useMenuList';
Expand All @@ -22,6 +24,8 @@ export const ControlledMenu = React.memo(function ControlledMenu({
isOpen,
isMounted,
menuItemFocus,
offsetX,
offsetY,
children,
onClick,
onClose,
Expand All @@ -39,7 +43,9 @@ export const ControlledMenu = React.memo(function ControlledMenu({
direction,
isOpen,
isMounted,
menuItemFocus
menuItemFocus,
offsetX,
offsetY
},
id,
animation,
Expand All @@ -51,6 +57,7 @@ export const ControlledMenu = React.memo(function ControlledMenu({

ControlledMenu.propTypes = {
...menuPropTypesBase,
...offsetPropTypes,
anchorPoint: PropTypes.exact({
x: PropTypes.number,
y: PropTypes.number
Expand All @@ -66,6 +73,7 @@ ControlledMenu.propTypes = {

ControlledMenu.defaultProps = {
...menuDefaultPropsBase,
...offsetDefaultProps,
isMounted: true,
menuItemFocus: { position: FocusPositions.INITIAL }
};
10 changes: 9 additions & 1 deletion src/components/Menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
safeCall,
menuPropTypesBase,
menuDefaultPropsBase,
offsetPropTypes,
offsetDefaultProps,
Keys,
FocusPositions,
useMenuChange,
Expand All @@ -23,6 +25,8 @@ export const Menu = React.memo(function Menu({
align,
direction,
menuButton,
offsetX,
offsetY,
children,
onClick,
onChange }) {
Expand Down Expand Up @@ -97,7 +101,9 @@ export const Menu = React.memo(function Menu({
direction,
isOpen,
isMounted,
menuItemFocus
menuItemFocus,
offsetX,
offsetY
},
id,
animation,
Expand All @@ -117,6 +123,7 @@ export const Menu = React.memo(function Menu({

Menu.propTypes = {
...menuPropTypesBase,
...offsetPropTypes,
keepMounted: PropTypes.bool,
menuButton: PropTypes.oneOfType([
PropTypes.element,
Expand All @@ -127,5 +134,6 @@ Menu.propTypes = {

Menu.defaultProps = {
...menuDefaultPropsBase,
...offsetDefaultProps,
keepMounted: true
};
13 changes: 8 additions & 5 deletions src/components/MenuList.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export const MenuList = defineName(React.memo(function MenuList({
isMounted,
isDisabled,
menuItemFocus,
offsetX,
offsetY,
children,
onKeyDown,
onAnimationEnd,
Expand Down Expand Up @@ -286,12 +288,12 @@ export const MenuList = defineName(React.memo(function MenuList({
} = positionHelpers();

const anchorRect = anchorRef.current.getBoundingClientRect();
const placeLeftX = anchorRect.left - containerRect.left - menuRect.width;
const placeRightX = anchorRect.right - containerRect.left;
const placeLeftorRightY = anchorRect.top - containerRect.top;
const placeLeftX = anchorRect.left - containerRect.left - menuRect.width - offsetX;
const placeRightX = anchorRect.right - containerRect.left + offsetX;
const placeLeftorRightY = anchorRect.top - containerRect.top + offsetY;

const placeTopY = anchorRect.top - containerRect.top - menuRect.height;
const placeBottomY = anchorRect.bottom - containerRect.top;
const placeTopY = anchorRect.top - containerRect.top - menuRect.height - offsetY;
const placeBottomY = anchorRect.bottom - containerRect.top + offsetY;
let placeToporBottomX;
if (align === 'end') {
placeToporBottomX = anchorRect.right - containerRect.left - menuRect.width;
Expand All @@ -301,6 +303,7 @@ export const MenuList = defineName(React.memo(function MenuList({
} else {
placeToporBottomX = anchorRect.left - containerRect.left;
}
placeToporBottomX += offsetX;

let newPosition, x, y;
let computedDirection = direction;
Expand Down
10 changes: 9 additions & 1 deletion src/components/SubMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
bem,
flatStyles,
stylePropTypes,
offsetPropTypes,
offsetDefaultProps,
menuClass,
subMenuClass,
menuItemClass,
Expand All @@ -31,6 +33,8 @@ export const SubMenu = defineName(React.memo(function SubMenu({
keepMounted,
label,
index,
offsetX,
offsetY,
children,
onChange }) {

Expand Down Expand Up @@ -175,7 +179,9 @@ export const SubMenu = defineName(React.memo(function SubMenu({
isOpen={isOpen}
isMounted={isMounted}
isDisabled={isDisabled}
menuItemFocus={menuItemFocus}>
menuItemFocus={menuItemFocus}
offsetX={offsetX}
offsetY={offsetY}>
{children}
</MenuList>
</li>
Expand All @@ -184,6 +190,7 @@ export const SubMenu = defineName(React.memo(function SubMenu({

SubMenu.propTypes = {
...stylePropTypes,
...offsetPropTypes,
'aria-label': PropTypes.string,
menuClassName: PropTypes.oneOfType([
PropTypes.string,
Expand All @@ -204,5 +211,6 @@ SubMenu.propTypes = {
};

SubMenu.defaultProps = {
...offsetDefaultProps,
keepMounted: true
};
33 changes: 0 additions & 33 deletions src/utils/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';

export const menuContainerClass = 'rc-menu-container';
export const menuClass = 'rc-menu';
Expand Down Expand Up @@ -43,35 +42,3 @@ export const CloseReason = Object.freeze({
'CANCEL': 'cancel',
'BLUR': 'blur'
});

export const stylePropTypes = {
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.func
]),
styles: PropTypes.oneOfType([
PropTypes.object,
PropTypes.func
]),
};

export const menuPropTypesBase = {
...stylePropTypes,
'aria-label': PropTypes.string,
id: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
animation: PropTypes.bool,
debugging: PropTypes.bool,
align: PropTypes.oneOf(['start', 'center', 'end']),
direction: PropTypes.oneOf(['left', 'right', 'top', 'bottom']),
children: PropTypes.node.isRequired,
onClick: PropTypes.func
};

export const menuDefaultPropsBase = {
animation: true,
align: 'start',
direction: 'bottom'
};
1 change: 1 addition & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './constants';
export * from './propTypes';
export * from './utils';
export * from './useActiveState';
export * from './useItemState';
Expand Down
43 changes: 43 additions & 0 deletions src/utils/propTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import PropTypes from 'prop-types';

export const stylePropTypes = {
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.func
]),
styles: PropTypes.oneOfType([
PropTypes.object,
PropTypes.func
]),
};

export const menuPropTypesBase = {
...stylePropTypes,
'aria-label': PropTypes.string,
id: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
animation: PropTypes.bool,
debugging: PropTypes.bool,
align: PropTypes.oneOf(['start', 'center', 'end']),
direction: PropTypes.oneOf(['left', 'right', 'top', 'bottom']),
children: PropTypes.node.isRequired,
onClick: PropTypes.func
};

export const menuDefaultPropsBase = {
animation: true,
align: 'start',
direction: 'bottom'
};

export const offsetPropTypes = {
offsetX: PropTypes.number,
offsetY: PropTypes.number
}

export const offsetDefaultProps = {
offsetX: 0,
offsetY: 0
}

0 comments on commit fc461a1

Please sign in to comment.