Skip to content

Commit

Permalink
Fix useRootPortal
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Mar 7, 2023
1 parent 10fe5d6 commit 704f13a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 21 deletions.
76 changes: 56 additions & 20 deletions packages/block-editor/src/components/block-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ import {
useLayoutEffect,
useContext,
useRef,
Fragment,
createElement,
useReducer,
useId,
} from '@wordpress/element';

/**
Expand All @@ -53,42 +52,79 @@ const pendingBlockVisibilityUpdatesPerRegistry = new WeakMap();

function useRootPortal( component ) {
const components = useContext( componentsContext );
const id = useId();

// Run every time the component rerenders.
useLayoutEffect( () => {
if ( ! component ) return;
components.add( component );
return () => {
components.delete( component );
};
} );
if ( component ) {
components.render( id, component );
} else {
components.unmount( id );
}
}, [ components, id, component ] );

// Run only on unmount.
useLayoutEffect( () => () => components.unmount( id ), [ components, id ] );
}

function Component( { id, componentsById, renderById } ) {
const [ , forceRender ] = useReducer( () => ( {} ) );
useLayoutEffect( () => {
renderById.current.set( id, forceRender );
}, [ id, renderById ] );
return componentsById.current.get( id );
}

function Components( { subscriber, components } ) {
function Components( { componentsById, renderById, renderAll } ) {
const [ , forceRender ] = useReducer( () => ( {} ) );
subscriber.current = forceRender;
return createElement( Fragment, null, ...components.current );

useLayoutEffect( () => {
renderAll.current = forceRender;
}, [ renderAll ] );

return Array.from( componentsById.current.keys() ).map( ( key ) => (
<Component
key={ key }
id={ key }
componentsById={ componentsById }
renderById={ renderById }
/>
) );
}

function ComponentRenderer( { children } ) {
const subscriber = useRef( () => {} );
const components = useRef( new Set() );
const componentsById = useRef( new Map() );
const renderById = useRef( new Map() );
const renderAll = useRef( () => {} );
return (
<componentsContext.Provider
value={ useMemo(
() => ( {
add( component ) {
components.current.add( component );
subscriber.current();
render( id, component ) {
if ( componentsById.current.has( id ) ) {
componentsById.current.set( id, component );
renderById.current.get( id )();
} else {
componentsById.current.set( id, component );
renderAll.current();
}
},
delete( component ) {
components.current.delete( component );
subscriber.current();
unmount( id ) {
if ( componentsById.current.has( id ) ) {
componentsById.current.delete( id );
renderById.current.delete( id );
renderAll.current();
}
},
} ),
[]
) }
>
<Components subscriber={ subscriber } components={ components } />
<Components
componentsById={ componentsById }
renderById={ renderById }
renderAll={ renderAll }
/>
{ children }
</componentsContext.Provider>
);
Expand Down
7 changes: 6 additions & 1 deletion packages/block-editor/src/hooks/duotone.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,10 @@ const useDuotoneStyles = ( props, blockType, attributes ) => {
);

const id = `wp-duotone-${ useInstanceId( useDuotoneStyles ) }`;
const duotoneStyle = attributes?.style?.color?.duotone;

BlockList.useRootPortal(
duotoneSupport && (
duotoneSupport && duotoneStyle && (
<ConditionalInlineDuotone
id={ id }
blockType={ blockType }
Expand All @@ -308,6 +309,10 @@ const useDuotoneStyles = ( props, blockType, attributes ) => {
)
);

// CAUTION: code added before this line will be executed
// for all blocks, not just those that support duotone. Code added
// above this line should be carefully evaluated for its impact on
// performance.
return {
...props,
className: duotoneSupport
Expand Down

0 comments on commit 704f13a

Please sign in to comment.