From ce769f0de253e9be0c6c9068db800c3dcbd85eaf Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 29 May 2023 11:47:01 +0200 Subject: [PATCH 1/5] Add new slotName prop --- packages/components/src/dropdown-menu-v2/index.tsx | 7 ++++++- packages/components/src/dropdown-menu-v2/types.ts | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/components/src/dropdown-menu-v2/index.tsx b/packages/components/src/dropdown-menu-v2/index.tsx index 7a0197f69fc3dd..d988a5bd4811eb 100644 --- a/packages/components/src/dropdown-menu-v2/index.tsx +++ b/packages/components/src/dropdown-menu-v2/index.tsx @@ -14,6 +14,7 @@ import { SVG, Circle } from '@wordpress/primitives'; /** * Internal dependencies */ +import { useSlot } from '../slot-fill'; import Icon from '../icon'; import * as DropdownMenuStyled from './styles'; import type { @@ -52,7 +53,11 @@ export const DropdownMenu = ( { // Render props children, trigger, + // Other props + slotName, }: DropdownMenuProps ) => { + const slot = useSlot( slotName ); + return ( { trigger } - + Date: Mon, 29 May 2023 11:47:32 +0200 Subject: [PATCH 2/5] Add storybook example --- .../src/dropdown-menu-v2/stories/index.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/components/src/dropdown-menu-v2/stories/index.tsx b/packages/components/src/dropdown-menu-v2/stories/index.tsx index 1171273028f9e1..ff2f425958d72e 100644 --- a/packages/components/src/dropdown-menu-v2/stories/index.tsx +++ b/packages/components/src/dropdown-menu-v2/stories/index.tsx @@ -20,6 +20,8 @@ import { DropdownSubMenuTrigger, } from '..'; import Button from '../../button'; +import Popover from '../../popover'; +import { Provider as SlotFillProvider } from '../../slot-fill'; /** * WordPress dependencies @@ -32,6 +34,8 @@ import { menu, wordpress } from '@wordpress/icons'; */ import Icon from '../../icon'; +const SLOT_NAME = 'dropdown-storybook-popover-slot'; + const meta: ComponentMeta< typeof DropdownMenu > = { title: 'Components (Experimental)/DropdownMenu v2', component: DropdownMenu, @@ -127,7 +131,11 @@ const RadioItemsGroup = () => { }; const Template: ComponentStory< typeof DropdownMenu > = ( props ) => ( - + + { /* @ts-expect-error Slot is not currently typed on Popover */ } + + + ); export const Default = Template.bind( {} ); Default.args = { @@ -191,3 +199,9 @@ Default.args = { ), }; + +export const WithCustomSlot = Template.bind( {} ); +WithCustomSlot.args = { + ...Default.args, + slotName: SLOT_NAME, +}; From e4927920c7643fccf016ed3067a0e12b21c8a97b Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 29 May 2023 11:47:46 +0200 Subject: [PATCH 3/5] Use context to use same slot for submenu portal --- .../components/src/dropdown-menu-v2/index.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/components/src/dropdown-menu-v2/index.tsx b/packages/components/src/dropdown-menu-v2/index.tsx index d988a5bd4811eb..1328ea14e985a7 100644 --- a/packages/components/src/dropdown-menu-v2/index.tsx +++ b/packages/components/src/dropdown-menu-v2/index.tsx @@ -6,7 +6,7 @@ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; /** * WordPress dependencies */ -import { forwardRef } from '@wordpress/element'; +import { forwardRef, createContext, useContext } from '@wordpress/element'; import { isRTL } from '@wordpress/i18n'; import { check, chevronRightSmall, lineSolid } from '@wordpress/icons'; import { SVG, Circle } from '@wordpress/primitives'; @@ -35,6 +35,12 @@ const SUB_MENU_OFFSET_SIDE = 12; // Opposite amount of the top padding of the menu item const SUB_MENU_OFFSET_ALIGN = -8; +const DropdownMenuPrivateContext = createContext< { + portalContainer: HTMLElement | null; +} >( { + portalContainer: null, +} ); + /** * `DropdownMenu` displays a menu to the user (such as a set of actions * or functions) triggered by a button. @@ -77,7 +83,11 @@ export const DropdownMenu = ( { alignOffset={ alignOffset } loop={ true } > - { children } + + { children } + @@ -123,6 +133,8 @@ export const DropdownSubMenu = ( { children, trigger, }: DropdownSubMenuProps ) => { + const { portalContainer } = useContext( DropdownMenuPrivateContext ); + return ( { trigger } - + Date: Mon, 29 May 2023 12:20:29 +0200 Subject: [PATCH 4/5] Use default popover slot instead of exposing a slotName prop, update Storybook --- packages/components/src/dropdown-menu-v2/index.tsx | 11 ++++++----- .../src/dropdown-menu-v2/stories/index.tsx | 12 ++---------- packages/components/src/dropdown-menu-v2/types.ts | 6 ------ packages/components/src/popover/index.tsx | 2 +- 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/packages/components/src/dropdown-menu-v2/index.tsx b/packages/components/src/dropdown-menu-v2/index.tsx index 1328ea14e985a7..b0617edd77f9f0 100644 --- a/packages/components/src/dropdown-menu-v2/index.tsx +++ b/packages/components/src/dropdown-menu-v2/index.tsx @@ -16,6 +16,7 @@ import { SVG, Circle } from '@wordpress/primitives'; */ import { useSlot } from '../slot-fill'; import Icon from '../icon'; +import { SLOT_NAME as POPOVER_DEFAULT_SLOT_NAME } from '../popover'; import * as DropdownMenuStyled from './styles'; import type { DropdownMenuProps, @@ -59,10 +60,10 @@ export const DropdownMenu = ( { // Render props children, trigger, - // Other props - slotName, }: DropdownMenuProps ) => { - const slot = useSlot( slotName ); + // Render the portal in the default slot used by the legacy Popover component. + const slot = useSlot( POPOVER_DEFAULT_SLOT_NAME ); + const portalContainer = slot.ref?.current; return ( { trigger } - + { children } diff --git a/packages/components/src/dropdown-menu-v2/stories/index.tsx b/packages/components/src/dropdown-menu-v2/stories/index.tsx index ff2f425958d72e..4bee7c902063f4 100644 --- a/packages/components/src/dropdown-menu-v2/stories/index.tsx +++ b/packages/components/src/dropdown-menu-v2/stories/index.tsx @@ -34,8 +34,6 @@ import { menu, wordpress } from '@wordpress/icons'; */ import Icon from '../../icon'; -const SLOT_NAME = 'dropdown-storybook-popover-slot'; - const meta: ComponentMeta< typeof DropdownMenu > = { title: 'Components (Experimental)/DropdownMenu v2', component: DropdownMenu, @@ -132,9 +130,9 @@ const RadioItemsGroup = () => { const Template: ComponentStory< typeof DropdownMenu > = ( props ) => ( - { /* @ts-expect-error Slot is not currently typed on Popover */ } - + { /* @ts-expect-error Slot is not currently typed on Popover */ } + ); export const Default = Template.bind( {} ); @@ -199,9 +197,3 @@ Default.args = { ), }; - -export const WithCustomSlot = Template.bind( {} ); -WithCustomSlot.args = { - ...Default.args, - slotName: SLOT_NAME, -}; diff --git a/packages/components/src/dropdown-menu-v2/types.ts b/packages/components/src/dropdown-menu-v2/types.ts index b2b251850ff19c..1fb246fafd6537 100644 --- a/packages/components/src/dropdown-menu-v2/types.ts +++ b/packages/components/src/dropdown-menu-v2/types.ts @@ -61,12 +61,6 @@ export type DropdownMenuProps = { * The contents of the dropdown */ children: React.ReactNode; - /** - * The name of the slot where the dropdown content should render. - * - * @default TODO - */ - slotName?: string; }; export type DropdownSubMenuTriggerProps = { diff --git a/packages/components/src/popover/index.tsx b/packages/components/src/popover/index.tsx index e1afb10035c306..0e7fb35c5f833f 100644 --- a/packages/components/src/popover/index.tsx +++ b/packages/components/src/popover/index.tsx @@ -74,7 +74,7 @@ import { overlayMiddlewares } from './overlay-middlewares'; * * @type {string} */ -const SLOT_NAME = 'Popover'; +export const SLOT_NAME = 'Popover'; // An SVG displaying a triangle facing down, filled with a solid // color and bordered in such a way to create an arrow-like effect. From 551f91b5fec5f0a40a1d0181ffbed4a1b51031e1 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 29 May 2023 12:23:09 +0200 Subject: [PATCH 5/5] CHANGELOG --- packages/components/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 4d6ea42e8bc0e1..b0880c5f6384a2 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -9,6 +9,7 @@ ### Experimental - `DropdownMenu` v2: Tweak styles ([#50967](https://github.com/WordPress/gutenberg/pull/50967)). +- `DropdownMenu` v2: Render in the default `Popover.Slot` ([#51046](https://github.com/WordPress/gutenberg/pull/51046)). ## 25.0.0 (2023-05-24)