@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
114 lines • 4.37 kB
JavaScript
import React, { isValidElement, useMemo } from 'react';
import Icon from '../../icon/Icon';
import { StyledContextMenuContentHeadline, StyledContextMenuContentItem, StyledContextMenuContentItemIconWrapper, StyledContextMenuContentItemSpacer, StyledContextMenuContentItemText, StyledContextMenuContentItemWrapper, StyledMotionContextMenuContent } from './ContextMenuContent.styles';
import { ContextMenuAlignment } from '../ContextMenu.types';
const ContextMenuContent = /*#__PURE__*/React.forwardRef(({
alignment,
coordinates,
items,
zIndex,
shouldHidePopupArrow,
headline,
onItemFocus,
focusedIndex,
onMouseEnter,
onMouseLeave
}, ref) => {
const isBottomLeftAlignment = alignment === ContextMenuAlignment.BottomLeft;
const isTopLeftAlignment = alignment === ContextMenuAlignment.TopLeft;
const isTopRightAlignment = alignment === ContextMenuAlignment.TopRight;
const isTopCenterAlignment = alignment === ContextMenuAlignment.TopCenter;
const isBottomCenterAlignment = alignment === ContextMenuAlignment.BottomCenter;
const percentageOffsetX = useMemo(() => {
if (isBottomLeftAlignment || isTopLeftAlignment) {
return -100;
}
if (isBottomCenterAlignment || isTopCenterAlignment) {
return -50;
}
return 0;
}, [isBottomCenterAlignment, isBottomLeftAlignment, isTopCenterAlignment, isTopLeftAlignment]);
const anchorOffsetX = useMemo(() => {
if (isBottomLeftAlignment || isTopLeftAlignment) {
return 15;
}
if (isBottomCenterAlignment || isTopCenterAlignment) {
return 0;
}
return -15;
}, [isBottomCenterAlignment, isBottomLeftAlignment, isTopCenterAlignment, isTopLeftAlignment]);
const percentageOffsetY = isTopRightAlignment || isTopLeftAlignment || isTopCenterAlignment ? -100 : 0;
const anchorOffsetY = isTopRightAlignment || isTopLeftAlignment || isTopCenterAlignment ? -21 : 21;
const exitAndInitialY = isTopLeftAlignment || isTopRightAlignment ? -16 : 16;
const content = useMemo(() => items.map(({
onClick,
key,
text,
icons,
shouldShowSpacer
}, index) => {
const isFocused = index === focusedIndex;
let iconElement = null;
if (/*#__PURE__*/isValidElement(icons)) {
iconElement = icons;
} else if (Array.isArray(icons) && icons.length > 0) {
iconElement = /*#__PURE__*/React.createElement(StyledContextMenuContentItemIconWrapper, null, /*#__PURE__*/React.createElement(Icon, {
icons: icons
}));
}
return /*#__PURE__*/React.createElement(StyledContextMenuContentItem, {
key: `context-menu-item-${key}`,
"data-index": index
}, /*#__PURE__*/React.createElement(StyledContextMenuContentItemWrapper, {
key: key,
onClick: event => {
event.preventDefault();
event.stopPropagation();
void onClick(event);
},
tabIndex: 0,
$shouldHidePopupArrow: shouldHidePopupArrow,
$isFocused: isFocused,
onFocus: () => onItemFocus(index)
}, iconElement, /*#__PURE__*/React.createElement(StyledContextMenuContentItemText, null, text)), shouldShowSpacer && /*#__PURE__*/React.createElement(StyledContextMenuContentItemSpacer, null));
}), [items, focusedIndex, shouldHidePopupArrow, onItemFocus]);
return /*#__PURE__*/React.createElement(StyledMotionContextMenuContent, {
animate: {
opacity: 1,
y: 0
},
exit: {
opacity: 0,
y: exitAndInitialY
},
initial: {
opacity: 0,
y: exitAndInitialY
},
$position: alignment,
$shouldHidePopupArrow: shouldHidePopupArrow,
$zIndex: zIndex,
ref: ref,
style: {
left: coordinates.x,
top: coordinates.y
},
transition: {
ease: 'anticipate'
},
transformTemplate: ({
y = '0px'
}) => `
translateX(${percentageOffsetX}%)
translateY(${percentageOffsetY}%)
translateX(${anchorOffsetX}px)
translateY(${anchorOffsetY}px)
translateY(${y})
`,
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave
}, headline && /*#__PURE__*/React.createElement(StyledContextMenuContentHeadline, null, headline), content);
});
ContextMenuContent.displayName = 'ContextMenuContent';
export default ContextMenuContent;
//# sourceMappingURL=ContextMenuContent.js.map