forked from mantinedev/mantine
/
PopoverDropdown.tsx
110 lines (100 loc) · 3.38 KB
/
PopoverDropdown.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
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
import React from 'react';
import { DefaultProps, useContextStylesApi, useComponentDefaultProps } from '@mantine/styles';
import { closeOnEscape } from '@mantine/utils';
import { useFocusReturn } from '@mantine/hooks';
import { FloatingArrow } from '../../Floating';
import { Box } from '../../Box';
import { Transition } from '../../Transition';
import { FocusTrap } from '../../FocusTrap';
import { OptionalPortal } from '../../Portal';
import { usePopoverContext } from '../Popover.context';
import useStyles from './PopoverDropdown.styles';
export interface PopoverDropdownProps extends DefaultProps, React.ComponentPropsWithoutRef<'div'> {
/** Dropdown content */
children?: React.ReactNode;
}
const defaultProps: Partial<PopoverDropdownProps> = {};
export function PopoverDropdown(props: PopoverDropdownProps) {
const { style, className, children, onKeyDownCapture, ...others } = useComponentDefaultProps(
'PopoverDropdown',
defaultProps,
props
);
const { classNames, styles, unstyled, staticSelector } = useContextStylesApi();
const ctx = usePopoverContext();
const { classes, cx } = useStyles(
{ radius: ctx.radius, shadow: ctx.shadow },
{ name: staticSelector, classNames, styles, unstyled }
);
const returnFocus = useFocusReturn({
opened: ctx.opened,
shouldReturnFocus: ctx.returnFocus,
});
const accessibleProps = ctx.withRoles
? {
'aria-labelledby': ctx.getTargetId(),
id: ctx.getDropdownId(),
role: 'dialog',
}
: {};
if (ctx.disabled) {
return null;
}
return (
<OptionalPortal withinPortal={ctx.withinPortal}>
<Transition
mounted={ctx.opened}
transition={ctx.transition}
duration={ctx.transitionDuration}
exitDuration={
typeof ctx.exitTransitionDuration === 'number'
? ctx.exitTransitionDuration
: ctx.transitionDuration
}
>
{(transitionStyles) => (
<FocusTrap active={ctx.trapFocus}>
<Box
{...accessibleProps}
tabIndex={-1}
key={ctx.placement}
ref={ctx.floating}
style={{
...style,
...transitionStyles,
zIndex: ctx.zIndex,
top: ctx.y ?? 0,
left: ctx.x ?? 0,
width: ctx.width === 'target' ? undefined : ctx.width,
}}
className={cx(classes.dropdown, className)}
onKeyDownCapture={closeOnEscape(ctx.onClose, {
active: ctx.closeOnEscape,
onTrigger: returnFocus,
onKeyDown: onKeyDownCapture,
})}
data-position={ctx.placement}
{...others}
>
{children}
<FloatingArrow
ref={ctx.arrowRef}
arrowX={ctx.arrowX}
arrowY={ctx.arrowY}
visible={ctx.withArrow}
withBorder
position={ctx.placement}
arrowSize={ctx.arrowSize}
arrowRadius={ctx.arrowRadius}
arrowOffset={ctx.arrowOffset}
arrowPosition={ctx.arrowPosition}
className={classes.arrow}
/>
</Box>
</FocusTrap>
)}
</Transition>
</OptionalPortal>
);
}
PopoverDropdown.displayName = '@mantine/core/PopoverDropdown';