/** * External dependencies */ import { Popover } from '@wordpress/components'; import classnames from 'classnames'; import { createElement, useEffect, useRef, createPortal, Children, useLayoutEffect, } from '@wordpress/element'; /** * Internal dependencies */ import { getMenuPropsType } from './types'; type MenuProps = { children?: JSX.Element | JSX.Element[]; getMenuProps: getMenuPropsType; isOpen: boolean; className?: string; position?: Popover.Position; scrollIntoViewOnOpen?: boolean; }; export const Menu = ( { children, getMenuProps, isOpen, className, position = 'bottom right', scrollIntoViewOnOpen = false, }: MenuProps ) => { const selectControlMenuRef = useRef< HTMLDivElement >( null ); const popoverRef = useRef< HTMLDivElement >( null ); useLayoutEffect( () => { const comboboxWrapper = selectControlMenuRef.current?.closest( '.woocommerce-experimental-select-control__combo-box-wrapper' ); const popoverContent = popoverRef.current?.querySelector< HTMLDivElement >( '.components-popover__content' ); if ( comboboxWrapper && comboboxWrapper?.clientWidth > 0 ) { if ( popoverContent ) { popoverContent.style.width = `${ comboboxWrapper.getBoundingClientRect().width }px`; } } }, [ selectControlMenuRef.current, selectControlMenuRef.current?.clientWidth, popoverRef.current, ] ); // Scroll the selected item into view when the menu opens. useEffect( () => { if ( isOpen && scrollIntoViewOnOpen ) { selectControlMenuRef.current?.scrollIntoView(); } }, [ isOpen, scrollIntoViewOnOpen ] ); /* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */ /* Disabled because of the onmouseup on the ul element below. */ return (
0, } ) } position={ position } animate={ false } resize={ false } ref={ popoverRef } >
    // Fix to prevent select control dropdown from closing when selecting within the Popover. e.stopPropagation() } > { isOpen && children }
); /* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */ }; export const MenuSlot: React.FC = () => createPortal(
{ /* @ts-expect-error name does exist on PopoverSlot see: https://github.com/WordPress/gutenberg/blob/trunk/packages/components/src/popover/index.tsx#L555 */ }
, document.body );