@itwin/itwinui-react
Version:
A react component library for iTwinUI
89 lines (88 loc) • 2.37 kB
JavaScript
import * as React from 'react';
import { mergeEventHandlers, useControlledState } from '../../utils/index.js';
import { Menu } from '../Menu/Menu.js';
import { FloatingTree } from '@floating-ui/react';
export const DropdownMenu = React.forwardRef((props, forwardedRef) =>
React.createElement(
FloatingTree,
null,
React.createElement(DropdownMenuContent, {
ref: forwardedRef,
...props,
}),
),
);
if ('development' === process.env.NODE_ENV)
DropdownMenu.displayName = 'DropdownMenu';
let DropdownMenuContent = React.forwardRef((props, forwardedRef) => {
let {
menuItems,
children,
role = 'menu',
visible: visibleProp,
placement = 'bottom-start',
matchWidth = false,
onVisibleChange,
portal = true,
middleware,
closeOnItemClick = false,
...rest
} = props;
let [visible, setVisible] = useControlledState(
false,
visibleProp,
onVisibleChange,
);
let close = React.useCallback(() => {
setVisible(false);
}, [setVisible]);
let menuContent = React.useMemo(() => {
if ('function' == typeof menuItems) return menuItems(close);
return menuItems;
}, [close, menuItems]);
let dropdownMenuContextValue = React.useMemo(
() => ({
close,
}),
[close],
);
return React.createElement(
DropdownMenuCloseOnClickContext.Provider,
{
value: closeOnItemClick,
},
React.createElement(
DropdownMenuContext.Provider,
{
value: dropdownMenuContextValue,
},
React.createElement(
Menu,
{
trigger: children,
onKeyDown: mergeEventHandlers(props.onKeyDown, (e) => {
if (e.defaultPrevented) return;
if ('Tab' === e.key) setVisible(false);
}),
role: role,
ref: forwardedRef,
portal: portal,
popoverProps: React.useMemo(
() => ({
placement,
matchWidth,
visible,
onVisibleChange: setVisible,
middleware,
}),
[matchWidth, middleware, placement, setVisible, visible],
),
...rest,
},
menuContent,
),
),
);
});
export const DropdownMenuContext = React.createContext(void 0);
export const DropdownMenuCloseOnClickContext = React.createContext(void 0);