-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathActionMenuItem.tsx
More file actions
124 lines (114 loc) · 3.95 KB
/
ActionMenuItem.tsx
File metadata and controls
124 lines (114 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { LegacyRef, Ref } from 'react'
import { Link } from 'react-router-dom'
import { Tooltip } from '@Common/Tooltip'
import { Icon } from '../Icon'
import { getTooltipProps } from '../SelectPicker/common'
import { ActionMenuItemProps } from './types'
export const ActionMenuItem = <T extends string | number>({
item,
itemRef,
isFocused,
onClick,
onMouseEnter,
disableDescriptionEllipsis = false,
}: ActionMenuItemProps<T>) => {
const {
id,
description,
label,
startIcon,
endIcon,
tooltipProps,
type = 'neutral',
isDisabled,
componentType = 'button',
} = item
// REFS
const ref: LegacyRef<HTMLLIElement> = (el) => {
if (isFocused && el) {
el.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
}
}
// CONSTANTS
const isNegativeType = type === 'negative'
// HANDLERS
const handleClick = () => {
onClick(item)
}
// RENDERERS
const renderIcon = (iconProps: typeof startIcon) =>
iconProps && (
<div className="mt-2 flex dc__no-shrink">
<Icon {...iconProps} color={iconProps.color || (isNegativeType ? 'R500' : 'N800')} />
</div>
)
const renderContent = () => (
<>
<Tooltip content={label} placement="right">
<span className={`m-0 fs-13 fw-4 lh-20 dc__truncate ${isNegativeType ? 'cr-5' : 'cn-9'}`}>{label}</span>
</Tooltip>
{description &&
(typeof description === 'string' ? (
<span
className={`m-0 fs-12 fw-4 lh-18 cn-7 ${!disableDescriptionEllipsis ? 'dc__ellipsis-right__2nd-line' : 'dc__word-break'}`}
>
{description}
</span>
) : (
description
))}
</>
)
const renderComponent = () => {
switch (componentType) {
case 'anchor':
return (
<a
ref={itemRef as LegacyRef<HTMLAnchorElement>}
className="flex-grow-1"
href={item.href}
target="_blank"
rel="noreferrer"
>
{renderContent()}
</a>
)
case 'link':
return (
<Link ref={itemRef as Ref<HTMLAnchorElement>} className="flex-grow-1" to={item.to}>
{renderContent()}
</Link>
)
case 'button':
default:
return (
<button
ref={itemRef as LegacyRef<HTMLButtonElement>}
type="button"
className="dc__transparent p-0 flex-grow-1"
>
{renderContent()}
</button>
)
}
}
return (
<Tooltip {...getTooltipProps(tooltipProps)}>
<li
ref={ref}
role="menuitem"
data-testid={`action-menu-item-${id}`}
onMouseEnter={onMouseEnter}
tabIndex={-1}
// Intentionally added margin to the left and right to have the gap on the edges of the options
className={`action-menu__option br-4 flex left top dc__gap-8 mr-4 ml-4 py-6 px-8 ${isDisabled ? 'dc__disabled' : 'cursor'} ${isNegativeType ? 'dc__hover-r50' : 'dc__hover-n50'} ${isFocused ? `action-menu__option--focused${isNegativeType ? '-negative' : ''}` : ''}`}
onClick={!isDisabled ? handleClick : undefined}
aria-disabled={isDisabled}
>
{renderIcon(startIcon)}
{renderComponent()}
{renderIcon(endIcon)}
</li>
</Tooltip>
)
}