File "LoopRenderer.js"
Full path: /home/webcknlt/admissiontell.com/wp-content/plugins/generateblocks/src/blocks/query-loop/components/LoopRenderer.js
File
size: 3.51 B (3.51 KB bytes)
MIME-type: text/x-java
Charset: utf-8
Download Open Edit Advanced Editor &nnbsp; Back
import {
BlockContextProvider,
InnerBlocks,
__experimentalUseBlockPreview as useBlockPreview, // eslint-disable-line @wordpress/no-unsafe-wp-apis
store as blockEditorStore,
} from '@wordpress/block-editor';
import { Spinner } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { memo, useEffect, useMemo, useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { useDebouncedCallback } from 'use-debounce';
function BlockPreview( {
blocks,
contextId,
setActiveContextId,
isHidden,
} ) {
const blockPreviewProps = useBlockPreview( {
blocks,
} );
const handleOnClick = () => setActiveContextId( contextId );
const style = {
display: isHidden ? 'none' : undefined,
};
return (
<div
{ ...blockPreviewProps }
className={ 'block-editor-inner-blocks gb-query-loop-block-preview' }
tabIndex={ 0 }
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
role={ 'button' }
onClick={ handleOnClick }
onKeyPress={ handleOnClick }
style={ style }
/>
);
}
const MemoizedBlockPreview = memo( BlockPreview );
function setIsBlockPreview( innerBlocks ) {
return innerBlocks.map( ( block ) => {
const newInnerBlocks = setIsBlockPreview( block.innerBlocks );
const attributes = Object.assign( {}, block.attributes, { isBlockPreview: true } );
return Object.assign( {}, block, { attributes, innerBlocks: newInnerBlocks } );
} );
}
export default function LoopRenderer( props ) {
const {
clientId,
data,
hasData,
isResolvingData,
hasResolvedData,
templateLock,
contextCallback,
} = props;
const innerBlocks = useSelect( ( select ) => {
return select( 'core/block-editor' )?.getBlocks( clientId );
}, [] );
const { getSelectedBlock } = useSelect( blockEditorStore );
const [ innerBlockData, setInnerBlockData ] = useState( [] );
const [ activeContextId, setActiveContextId ] = useState();
useEffect( () => {
setInnerBlockData( setIsBlockPreview( innerBlocks ) );
}, [] );
const debounced = useDebouncedCallback( () => {
setInnerBlockData( setIsBlockPreview( innerBlocks ) );
}, 10 );
const debounceBlocks = [
'core/paragraph',
'core/heading',
'core/button',
'generateblocks/headline',
'generateblocks/button',
];
useEffect( () => {
const selectedBlock = getSelectedBlock();
if (
debounceBlocks.includes( selectedBlock?.name ) &&
! selectedBlock?.attributes?.useDynamicData &&
! selectedBlock?.attributes?.dynamicContentType
) {
// Only debounce if we're using a RichText component.
debounced();
} else {
setInnerBlockData( setIsBlockPreview( innerBlocks ) );
}
}, [ JSON.stringify( innerBlocks ) ] );
const dataContexts = useMemo(
() =>
hasData && data.map( ( item ) => ( contextCallback( item ) ) ),
[ data, hasData ]
);
if ( isResolvingData ) {
return ( <Spinner /> );
}
if ( hasResolvedData && ! hasData ) {
return ( <h5>{ __( 'No results found.', 'generateblocks' ) }</h5> );
}
return (
dataContexts &&
dataContexts.map( ( postContext ) => (
<BlockContextProvider key={ postContext.postId } value={ postContext }>
{ postContext.postId === ( activeContextId || dataContexts[ 0 ]?.postId )
? ( <InnerBlocks { ...props } templateLock={ templateLock } /> )
: null
}
<MemoizedBlockPreview
blocks={ innerBlockData }
contextId={ postContext.postId }
setActiveContextId={ setActiveContextId }
isHidden={ postContext.postId === ( activeContextId || dataContexts[ 0 ]?.postId ) }
/>
</BlockContextProvider>
) ) );
}