2022-09-13 07:36:00 +00:00
|
|
|
import { Theme } from '@mui/material';
|
2022-08-26 09:54:03 +00:00
|
|
|
import React, { ReactNode } from 'react';
|
2021-12-15 13:18:41 +00:00
|
|
|
import { useSelector } from 'react-redux';
|
2022-09-13 07:36:00 +00:00
|
|
|
import { makeStyles } from 'tss-react/mui';
|
2021-12-15 13:18:41 +00:00
|
|
|
|
2022-10-06 10:09:40 +00:00
|
|
|
import { showOverflowDrawer } from '../../../../toolbox/functions.web';
|
|
|
|
import Icon from '../../../icons/components/Icon';
|
|
|
|
import { withPixelLineHeight } from '../../../styles/functions.web';
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
export type Props = {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Label used for accessibility.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
accessibilityLabel: string;
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* CSS class name used for custom styles.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
className?: string;
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Custom icon. If used, the icon prop is ignored.
|
|
|
|
* Used to allow custom children instead of just the default icons.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
customIcon?: ReactNode;
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether or not the action is disabled.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
disabled?: boolean;
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
/**
|
2022-08-26 09:54:03 +00:00
|
|
|
* Default icon for action.
|
2021-12-15 13:18:41 +00:00
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
icon?: Function;
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
/**
|
2022-08-26 09:54:03 +00:00
|
|
|
* Id of the action container.
|
2021-12-15 13:18:41 +00:00
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
id?: string;
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Click handler.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
onClick?: (e?: React.MouseEvent) => void;
|
2021-12-15 13:18:41 +00:00
|
|
|
|
2022-04-05 12:19:03 +00:00
|
|
|
/**
|
|
|
|
* Keydown handler.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
onKeyDown?: (e?: React.KeyboardEvent) => void;
|
2022-04-05 12:19:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Keypress handler.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
onKeyPress?: (e?: React.KeyboardEvent) => void;
|
2022-04-05 12:19:03 +00:00
|
|
|
|
2022-04-08 19:11:37 +00:00
|
|
|
/**
|
|
|
|
* TestId of the element, if any.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
testId?: string;
|
2022-04-08 19:11:37 +00:00
|
|
|
|
2021-12-15 13:18:41 +00:00
|
|
|
/**
|
|
|
|
* Action text.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
text: string;
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class name for the text.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
textClassName?: string;
|
|
|
|
};
|
2021-12-15 13:18:41 +00:00
|
|
|
|
2022-09-13 07:36:00 +00:00
|
|
|
const useStyles = makeStyles()((theme: Theme) => {
|
2021-12-15 13:18:41 +00:00
|
|
|
return {
|
|
|
|
contextMenuItem: {
|
|
|
|
alignItems: 'center',
|
|
|
|
cursor: 'pointer',
|
|
|
|
display: 'flex',
|
|
|
|
minHeight: '40px',
|
|
|
|
padding: '10px 16px',
|
|
|
|
boxSizing: 'border-box',
|
|
|
|
|
|
|
|
'& > *:not(:last-child)': {
|
2022-09-13 07:36:00 +00:00
|
|
|
marginRight: theme.spacing(3)
|
2021-12-15 13:18:41 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
'&:hover': {
|
2022-10-06 10:09:40 +00:00
|
|
|
backgroundColor: theme.palette.ui02
|
|
|
|
},
|
|
|
|
|
|
|
|
'&:active': {
|
|
|
|
backgroundColor: theme.palette.ui03
|
2021-12-15 13:18:41 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
contextMenuItemDisabled: {
|
|
|
|
pointerEvents: 'none'
|
|
|
|
},
|
|
|
|
|
|
|
|
contextMenuItemDrawer: {
|
2022-10-06 10:09:40 +00:00
|
|
|
padding: '13px 16px'
|
2021-12-15 13:18:41 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
contextMenuItemIcon: {
|
|
|
|
'& svg': {
|
|
|
|
fill: theme.palette.icon01
|
|
|
|
}
|
2022-10-06 10:09:40 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
text: {
|
|
|
|
...withPixelLineHeight(theme.typography.bodyShortRegular),
|
|
|
|
color: theme.palette.text01
|
|
|
|
},
|
|
|
|
|
|
|
|
drawerText: {
|
|
|
|
...withPixelLineHeight(theme.typography.bodyShortRegularLarge)
|
2021-12-15 13:18:41 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
const ContextMenuItem = ({
|
|
|
|
accessibilityLabel,
|
|
|
|
className,
|
|
|
|
customIcon,
|
|
|
|
disabled,
|
|
|
|
id,
|
|
|
|
icon,
|
|
|
|
onClick,
|
2022-04-05 12:19:03 +00:00
|
|
|
onKeyDown,
|
|
|
|
onKeyPress,
|
2022-04-08 19:11:37 +00:00
|
|
|
testId,
|
2021-12-15 13:18:41 +00:00
|
|
|
text,
|
|
|
|
textClassName }: Props) => {
|
2022-09-13 07:36:00 +00:00
|
|
|
const { classes: styles, cx } = useStyles();
|
2022-08-26 09:54:03 +00:00
|
|
|
const _overflowDrawer: boolean = useSelector(showOverflowDrawer);
|
2021-12-15 13:18:41 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div
|
2022-04-05 12:19:03 +00:00
|
|
|
aria-disabled = { disabled }
|
2021-12-15 13:18:41 +00:00
|
|
|
aria-label = { accessibilityLabel }
|
2022-09-13 07:36:00 +00:00
|
|
|
className = { cx(styles.contextMenuItem,
|
2021-12-15 13:18:41 +00:00
|
|
|
_overflowDrawer && styles.contextMenuItemDrawer,
|
|
|
|
disabled && styles.contextMenuItemDisabled,
|
|
|
|
className
|
|
|
|
) }
|
2022-04-08 19:11:37 +00:00
|
|
|
data-testid = { testId }
|
2021-12-15 13:18:41 +00:00
|
|
|
id = { id }
|
|
|
|
key = { text }
|
2022-04-05 12:19:03 +00:00
|
|
|
onClick = { disabled ? undefined : onClick }
|
|
|
|
onKeyDown = { disabled ? undefined : onKeyDown }
|
|
|
|
onKeyPress = { disabled ? undefined : onKeyPress }>
|
2021-12-15 13:18:41 +00:00
|
|
|
{customIcon ? customIcon
|
|
|
|
: icon && <Icon
|
|
|
|
className = { styles.contextMenuItemIcon }
|
|
|
|
size = { 20 }
|
|
|
|
src = { icon } />}
|
2022-10-06 10:09:40 +00:00
|
|
|
<span className = { cx(textClassName) }>{text}</span>
|
2021-12-15 13:18:41 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default ContextMenuItem;
|