You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ContextMenuItem.tsx 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import React, { ReactNode } from 'react';
  2. import { useSelector } from 'react-redux';
  3. import { makeStyles } from 'tss-react/mui';
  4. import { showOverflowDrawer } from '../../../../toolbox/functions.web';
  5. import Icon from '../../../icons/components/Icon';
  6. import { withPixelLineHeight } from '../../../styles/functions.web';
  7. export interface IProps {
  8. /**
  9. * Label used for accessibility.
  10. */
  11. accessibilityLabel: string;
  12. /**
  13. * Component children.
  14. */
  15. children?: ReactNode;
  16. /**
  17. * CSS class name used for custom styles.
  18. */
  19. className?: string;
  20. /**
  21. * Custom icon. If used, the icon prop is ignored.
  22. * Used to allow custom children instead of just the default icons.
  23. */
  24. customIcon?: ReactNode;
  25. /**
  26. * Whether or not the action is disabled.
  27. */
  28. disabled?: boolean;
  29. /**
  30. * Default icon for action.
  31. */
  32. icon?: Function;
  33. /**
  34. * Id of the action container.
  35. */
  36. id?: string;
  37. /**
  38. * Click handler.
  39. */
  40. onClick?: (e?: React.MouseEvent) => void;
  41. /**
  42. * Keydown handler.
  43. */
  44. onKeyDown?: (e?: React.KeyboardEvent) => void;
  45. /**
  46. * Keypress handler.
  47. */
  48. onKeyPress?: (e?: React.KeyboardEvent) => void;
  49. /**
  50. * Whether the item is marked as selected.
  51. */
  52. selected?: boolean;
  53. /**
  54. * TestId of the element, if any.
  55. */
  56. testId?: string;
  57. /**
  58. * Action text.
  59. */
  60. text?: string;
  61. /**
  62. * Class name for the text.
  63. */
  64. textClassName?: string;
  65. }
  66. const useStyles = makeStyles()(theme => {
  67. return {
  68. contextMenuItem: {
  69. alignItems: 'center',
  70. cursor: 'pointer',
  71. display: 'flex',
  72. minHeight: '40px',
  73. padding: '10px 16px',
  74. boxSizing: 'border-box',
  75. '& > *:not(:last-child)': {
  76. marginRight: theme.spacing(3)
  77. },
  78. '&:hover': {
  79. backgroundColor: theme.palette.ui02
  80. },
  81. '&:active': {
  82. backgroundColor: theme.palette.ui03
  83. },
  84. '&:focus': {
  85. boxShadow: `inset 0 0 0 2px ${theme.palette.action01Hover}`
  86. }
  87. },
  88. selected: {
  89. borderLeft: `3px solid ${theme.palette.action01Hover}`,
  90. paddingLeft: '13px',
  91. backgroundColor: theme.palette.ui02
  92. },
  93. contextMenuItemDisabled: {
  94. pointerEvents: 'none'
  95. },
  96. contextMenuItemDrawer: {
  97. padding: '13px 16px'
  98. },
  99. contextMenuItemIcon: {
  100. '& svg': {
  101. fill: theme.palette.icon01
  102. }
  103. },
  104. text: {
  105. ...withPixelLineHeight(theme.typography.bodyShortRegular),
  106. color: theme.palette.text01
  107. },
  108. drawerText: {
  109. ...withPixelLineHeight(theme.typography.bodyShortRegularLarge)
  110. }
  111. };
  112. });
  113. const ContextMenuItem = ({
  114. accessibilityLabel,
  115. children,
  116. className,
  117. customIcon,
  118. disabled,
  119. id,
  120. icon,
  121. onClick,
  122. onKeyDown,
  123. onKeyPress,
  124. selected,
  125. testId,
  126. text,
  127. textClassName }: IProps) => {
  128. const { classes: styles, cx } = useStyles();
  129. const _overflowDrawer: boolean = useSelector(showOverflowDrawer);
  130. return (
  131. <div
  132. aria-disabled = { disabled }
  133. aria-label = { accessibilityLabel }
  134. className = { cx(styles.contextMenuItem,
  135. _overflowDrawer && styles.contextMenuItemDrawer,
  136. disabled && styles.contextMenuItemDisabled,
  137. selected && styles.selected,
  138. className
  139. ) }
  140. data-testid = { testId }
  141. id = { id }
  142. key = { text }
  143. onClick = { disabled ? undefined : onClick }
  144. onKeyDown = { disabled ? undefined : onKeyDown }
  145. onKeyPress = { disabled ? undefined : onKeyPress }
  146. role = 'button'
  147. tabIndex = { disabled ? undefined : 0 }>
  148. {customIcon ? customIcon
  149. : icon && <Icon
  150. className = { styles.contextMenuItemIcon }
  151. size = { 20 }
  152. src = { icon } />}
  153. {text && (
  154. <span
  155. className = { cx(styles.text,
  156. _overflowDrawer && styles.drawerText,
  157. textClassName) }>
  158. {text}
  159. </span>
  160. )}
  161. {children}
  162. </div>
  163. );
  164. };
  165. export default ContextMenuItem;