diff --git a/packages/js/components/changelog/add-34331_popover_to_select_control_dropdown b/packages/js/components/changelog/add-34331_popover_to_select_control_dropdown
new file mode 100644
index 00000000000..20f4ddf6ee3
--- /dev/null
+++ b/packages/js/components/changelog/add-34331_popover_to_select_control_dropdown
@@ -0,0 +1,4 @@
+Significance: minor
+Type: update
+
+Add support in SelectControl for using the popover slot for the popover.
diff --git a/packages/js/components/src/experimental-select-control/menu.scss b/packages/js/components/src/experimental-select-control/menu.scss
index 3592eec2d9b..7c1f126b447 100644
--- a/packages/js/components/src/experimental-select-control/menu.scss
+++ b/packages/js/components/src/experimental-select-control/menu.scss
@@ -5,13 +5,25 @@
left: 0;
margin-top: $gap-smaller;
box-sizing: border-box;
- display: none;
+}
+
+.components-popover.woocommerce-experimental-select-control__popover-menu {
background: $studio-white;
border: 1px solid $studio-gray-5;
border-radius: 3px;
- z-index: 10;
-
+ display: none;
&.is-open.has-results {
display: block;
}
}
+.woocommerce-experimental-select-control__popover-menu-container {
+ margin: 0;
+ max-height: 300px;
+ overflow-y: scroll;
+
+ > .category-field-dropdown__item:not( :first-child ) {
+ .category-field-dropdown__item-content {
+ border-top: 1px solid $gray-200;
+ }
+ }
+}
diff --git a/packages/js/components/src/experimental-select-control/menu.tsx b/packages/js/components/src/experimental-select-control/menu.tsx
index 22e2adb552b..5b5cd8de526 100644
--- a/packages/js/components/src/experimental-select-control/menu.tsx
+++ b/packages/js/components/src/experimental-select-control/menu.tsx
@@ -1,8 +1,15 @@
/**
* External dependencies
*/
+import { Popover } from '@wordpress/components';
import classnames from 'classnames';
-import { createElement } from '@wordpress/element';
+import {
+ createElement,
+ useEffect,
+ useRef,
+ useState,
+ createPortal,
+} from '@wordpress/element';
/**
* Internal dependencies
@@ -22,21 +29,63 @@ export const Menu = ( {
isOpen,
className,
}: MenuProps ) => {
+ const [ boundingRect, setBoundingRect ] = useState< DOMRect >();
+ const selectControlMenuRef = useRef< HTMLDivElement >( null );
+
+ useEffect( () => {
+ if ( selectControlMenuRef.current?.parentElement ) {
+ setBoundingRect(
+ selectControlMenuRef.current.parentElement.getBoundingClientRect()
+ );
+ }
+ }, [ selectControlMenuRef.current ] );
+
+ /* 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 (
-
- { isOpen && children }
-
+ 0,
+ }
+ ) }
+ position="bottom center"
+ animate={ false }
+ >
+
+ // 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(
+ ,
+ document.body
+ );
diff --git a/packages/js/components/src/experimental-select-control/stories/index.tsx b/packages/js/components/src/experimental-select-control/stories/index.tsx
index c36cae46cfd..c13f9c88ebd 100644
--- a/packages/js/components/src/experimental-select-control/stories/index.tsx
+++ b/packages/js/components/src/experimental-select-control/stories/index.tsx
@@ -1,7 +1,13 @@
/**
* External dependencies
*/
-import { CheckboxControl, Spinner } from '@wordpress/components';
+import {
+ Button,
+ CheckboxControl,
+ Modal,
+ SlotFillProvider,
+ Spinner,
+} from '@wordpress/components';
import React from 'react';
import { createElement, useState } from '@wordpress/element';
@@ -11,7 +17,7 @@ import { createElement, useState } from '@wordpress/element';
import { SelectedType, DefaultItemType, getItemLabelType } from '../types';
import { MenuItem } from '../menu-item';
import { SelectControl, selectControlStateChangeTypes } from '../';
-import { Menu } from '../menu';
+import { Menu, MenuSlot } from '../menu';
const sampleItems = [
{ value: 'apple', label: 'Apple' },
@@ -365,6 +371,45 @@ export const CustomItemType: React.FC = () => {
);
};
+export const SingleWithinModalUsingBodyDropdownPlacement: React.FC = () => {
+ const [ isOpen, setOpen ] = useState( true );
+ const [ selected, setSelected ] =
+ useState< SelectedType< DefaultItemType > >();
+ const [ selectedTwo, setSelectedTwo ] =
+ useState< SelectedType< DefaultItemType > >();
+
+ return (
+
+ Selected: { JSON.stringify( selected ) }
+
+ { isOpen && (
+ setOpen( false ) }
+ >
+ item && setSelected( item ) }
+ onRemove={ () => setSelected( null ) }
+ />
+ item && setSelectedTwo( item ) }
+ onRemove={ () => setSelectedTwo( null ) }
+ />
+
+ ) }
+
+
+ );
+};
+
export default {
title: 'WooCommerce Admin/experimental/SelectControl',
component: SelectControl,
diff --git a/packages/js/components/src/index.ts b/packages/js/components/src/index.ts
index 19663facc15..a4c2248355f 100644
--- a/packages/js/components/src/index.ts
+++ b/packages/js/components/src/index.ts
@@ -49,7 +49,10 @@ export {
MenuItem as __experimentalSelectControlMenuItem,
MenuItemProps as __experimentalSelectControlMenuItemProps,
} from './experimental-select-control/menu-item';
-export { Menu as __experimentalSelectControlMenu } from './experimental-select-control/menu';
+export {
+ Menu as __experimentalSelectControlMenu,
+ MenuSlot as __experimentalSelectControlMenuSlot,
+} from './experimental-select-control/menu';
export { default as ScrollTo } from './scroll-to';
export { Sortable } from './sortable';
export { ListItem } from './list-item';