forked from mantinedev/mantine
/
MenuTarget.tsx
51 lines (42 loc) · 1.43 KB
/
MenuTarget.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
import React, { cloneElement, forwardRef } from 'react';
import { isElement, createEventHandler } from '@mantine/utils';
import { useMenuContext } from '../Menu.context';
import { Popover } from '../../Popover';
import { MENU_ERRORS } from '../Menu.errors';
export interface MenuTargetProps {
/** Target element */
children: React.ReactNode;
/** Key of the prop that should be used to get element ref */
refProp?: string;
}
export const MenuTarget = forwardRef<HTMLElement, MenuTargetProps>(
({ children, refProp = 'ref', ...others }, ref) => {
if (!isElement(children)) {
throw new Error(MENU_ERRORS.children);
}
const ctx = useMenuContext();
const onClick = createEventHandler(
children.props.onClick,
() => ctx.trigger === 'click' && ctx.toggleDropdown()
);
const onMouseEnter = createEventHandler(
children.props.onMouseEnter,
() => ctx.trigger === 'hover' && ctx.openDropdown()
);
const onMouseLeave = createEventHandler(
children.props.onMouseLeave,
() => ctx.trigger === 'hover' && ctx.closeDropdown()
);
return (
<Popover.Target refProp={refProp} popupType="menu" ref={ref} {...others}>
{cloneElement(children, {
onClick,
onMouseEnter,
onMouseLeave,
'data-expanded': ctx.opened ? true : undefined,
})}
</Popover.Target>
);
}
);
MenuTarget.displayName = '@mantine/core/MenuTarget';