Popover

View on Storybook

View source on GitHub

Import

import { Popover } from '@wordpress/components';

Props

NameTypeDefaultRequiredDescription
namestring'Popover'

The name of the Slot in which the popover should be rendered. It should be also passed to the corresponding PopoverSlot component.

@default ‘Popover’

Examples

Default

const Default = () => <Popover>(<div style={ { width: '280px', whiteSpace: 'normal' } }>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
                        eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
                        enim ad minim veniam, quis nostrud exercitation ullamco laboris
                        nisi ut aliquip ex ea commodo consequat.
                    </div>)</Popover>;

Unstyled

const Unstyled = () => <Popover variant="unstyled" />;

All Placements

const AllPlacements = ( { children, ...args } ) => (
    <div
        style={ {
            minWidth: '600px',
            marginLeft: 'auto',
            marginRight: 'auto',
        } }
    >
        <h2>
            Resize / scroll the viewport to test the behavior of the
            popovers when they reach the viewport boundaries.
        </h2>
        <div>
            { AVAILABLE_PLACEMENTS.map( ( p ) => (
                <PopoverWithAnchor
                    key={ p }
                    placement={ p }
                    { ...args }
                    resize={ p === 'overlay' ? true : args.resize }
                >
                    { children }
                    <div>
                        <small>(placement: { p })</small>
                    </div>
                </PopoverWithAnchor>
            ) ) }
        </div>
    </div>
);

Dynamic Height

const DynamicHeight = () => <Popover>(<div
        style={ {
            height: 'var(--dynamic-height)',
            background: '#eee',
            padding: '20px',
        } }
    >Content with dynamic height
                    </div>)</Popover>;

With Slot Outside Iframe

const WithSlotOutsideIframe = () => <PopoverInsideIframeRenderedInExternalSlot />;

With Close Handlers

const WithCloseHandlers = function WithCloseHandlersStory( args ) {
    const [ isVisible, setIsVisible ] = useState( false );
    const buttonRef = useRef< HTMLButtonElement >( null );

    const toggleVisible = ( event: React.MouseEvent ) => {
        if ( buttonRef.current && event.target !== buttonRef.current ) {
            return;
        }
        setIsVisible( ( prev ) => ! prev );
    };

    const handleClose = () => {
        args.onClose?.();
        setIsVisible( false );
    };

    const handleFocusOutside = ( e: React.SyntheticEvent ) => {
        args.onFocusOutside?.( e );
        setIsVisible( false );
    };

    useEffect( () => {
        buttonRef.current?.scrollIntoView( {
            block: 'center',
            inline: 'center',
        } );
    }, [] );

    return (
        <div
            style={ {
                width: '300vw',
                height: '300vh',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
            } }
        >
            <Button
                __next40pxDefaultSize
                variant="secondary"
                onClick={ toggleVisible }
                ref={ buttonRef }
            >
                Toggle Popover
                { isVisible && (
                    <Popover
                        { ...args }
                        onClose={ handleClose }
                        onFocusOutside={ handleFocusOutside }
                    >
                        { args.children }
                    </Popover>
                ) }
            </Button>
        </div>
    );
};