diff --git a/packages/components/src/border-box-control/border-box-control-split-controls/component.tsx b/packages/components/src/border-box-control/border-box-control-split-controls/component.tsx index d5cf6e2ca3370..da72c22a2868b 100644 --- a/packages/components/src/border-box-control/border-box-control-split-controls/component.tsx +++ b/packages/components/src/border-box-control/border-box-control-split-controls/component.tsx @@ -1,12 +1,8 @@ -/** - * External dependencies - */ -import type { ComponentProps } from 'react'; /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { useRef } from '@wordpress/element'; +import { useCallback, useState, useEffect } from '@wordpress/element'; import { useMergeRefs } from '@wordpress/compose'; /** @@ -18,6 +14,7 @@ import { Grid } from '../../grid'; import { contextConnect, WordPressComponentProps } from '../../ui/context'; import { useBorderBoxControlSplitControls } from './hook'; +import type { BorderControlProps } from '../../border-control/types'; import type { SplitControlsProps } from '../types'; const BorderBoxControlSplitControls = ( @@ -40,18 +37,27 @@ const BorderBoxControlSplitControls = ( __next36pxDefaultSize, ...otherProps } = useBorderBoxControlSplitControls( props ); - const containerRef = useRef(); - const mergedRef = useMergeRefs( [ containerRef, forwardedRef ] ); - const popoverProps: ComponentProps< - typeof BorderControl - >[ '__unstablePopoverProps' ] = popoverPlacement - ? { + + const [ popoverProps, setPopoverProps ] = + useState< BorderControlProps[ '__unstablePopoverProps' ] >(); + const [ popoverAnchor, setPopoverAnchor ] = useState< Element >(); + + const containerRef = useCallback( ( node ) => { + setPopoverAnchor( node ?? undefined ); + }, [] ); + + useEffect( () => { + if ( popoverPlacement ) { + setPopoverProps( { placement: popoverPlacement, offset: popoverOffset, - anchorRef: containerRef, + anchor: popoverAnchor, shift: true, - } - : undefined; + } ); + } else { + setPopoverProps( undefined ); + } + }, [ popoverPlacement, popoverOffset, popoverAnchor ] ); const sharedBorderControlProps = { colors, @@ -64,6 +70,8 @@ const BorderBoxControlSplitControls = ( __next36pxDefaultSize, }; + const mergedRef = useMergeRefs( [ containerRef, forwardedRef ] ); + return ( { const { label, hideLabelFromVision } = props; @@ -67,18 +65,29 @@ const BorderBoxControl = ( __next36pxDefaultSize = false, ...otherProps } = useBorderBoxControl( props ); - const containerRef = useRef(); - const mergedRef = useMergeRefs( [ containerRef, forwardedRef ] ); - const popoverProps: ComponentProps< - typeof BorderControl - >[ '__unstablePopoverProps' ] = popoverPlacement - ? { + + const [ popoverProps, setPopoverProps ] = + useState< BorderControlProps[ '__unstablePopoverProps' ] >(); + const [ popoverAnchor, setPopoverAnchor ] = useState< Element >(); + + const containerRef = useCallback( ( node ) => { + setPopoverAnchor( node ?? undefined ); + }, [] ); + + useEffect( () => { + if ( popoverPlacement ) { + setPopoverProps( { placement: popoverPlacement, offset: popoverOffset, - anchorRef: containerRef, + anchor: popoverAnchor, shift: true, - } - : undefined; + } ); + } else { + setPopoverProps( undefined ); + } + }, [ popoverPlacement, popoverOffset, popoverAnchor ] ); + + const mergedRef = useMergeRefs( [ containerRef, forwardedRef ] ); return ( diff --git a/packages/components/src/border-box-control/stories/index.js b/packages/components/src/border-box-control/stories/index.js index 1f6413fa50ab0..469d6d4d3407f 100644 --- a/packages/components/src/border-box-control/stories/index.js +++ b/packages/components/src/border-box-control/stories/index.js @@ -85,6 +85,7 @@ Default.args = { width: '1px', }, __next36pxDefaultSize: false, + popoverPlacement: 'right-start', }; const WrapperView = styled.div` diff --git a/packages/components/src/popover/types.ts b/packages/components/src/popover/types.ts index ea00169f7d722..b4b6d8c24fc41 100644 --- a/packages/components/src/popover/types.ts +++ b/packages/components/src/popover/types.ts @@ -41,7 +41,7 @@ export type PopoverProps = { * be an `Element` or, alternatively, a `VirtualElement` — ie. an object with * the `getBoundingClientRect()` and the `ownerDocument` properties defined. */ - anchor: Element | VirtualElement; + anchor?: Element | VirtualElement; /** * Whether the popover should animate when opening. *