-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathmenu-item.tsx
69 lines (62 loc) · 1.77 KB
/
menu-item.tsx
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
import React, { ComponentProps, FC, useEffect, useRef } from 'react'
import classNames from 'classnames'
import { EbayBadge } from '../ebay-badge'
import { EbayIcon } from '../ebay-icon'
import { EbayMenuType } from './types'
export type MenuItemProps = ComponentProps<'div'> & {
type?: EbayMenuType;
focused?: boolean;
tabIndex?: number;
checked?: boolean;
value?: string;
disabled?: boolean;
badgeNumber?: number;
badgeAriaLabel?: string;
}
const EbayMenuItem: FC<MenuItemProps> = ({
className,
checked,
type,
focused = false,
tabIndex,
disabled,
badgeNumber,
badgeAriaLabel,
children,
...rest
}) => {
const ref = useRef(null)
const hasBadge = badgeNumber !== undefined
useEffect(() => {
if (ref.current && focused) {
ref.current.focus()
}
}, [ref, focused])
const checkable: EbayMenuType[] = ['radio', 'checkbox']
return (
<div
aria-label={badgeAriaLabel}
{...rest}
ref={ref}
className={classNames(className, 'menu__item', hasBadge && 'menu__item--badged')}
role={roleFromType(type)}
aria-checked={checkable.includes(type) ? checked : undefined}
aria-disabled={disabled}
tabIndex={focused ? 0 : tabIndex}
>
<span aria-hidden={hasBadge}>
{children}
{hasBadge && <EbayBadge type="menu" number={badgeNumber} />}
</span>
<EbayIcon name="tick16" />
</div>
)
}
function roleFromType(type: EbayMenuType) {
const roles: Record<EbayMenuType, string> = {
radio: 'menuitemradio',
checkbox: 'menuitemcheckbox'
}
return roles[type] || 'menuitem'
}
export default EbayMenuItem