| Server IP : 185.252.147.100 / Your IP : 216.73.217.33 Web Server : nginx/1.27.3 System : Linux mitrofanov.ru 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64 User : mitr ( 1000) PHP Version : 8.2.29 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /proc/self/cwd/wp-content/plugins/generateblocks/src/pattern-library/components/ |
Upload File : |
import Pattern from './pattern';
import { useLibrary } from './library-provider';
import { useMemo, useRef, useState, useEffect, memo } from '@wordpress/element';
import { Button, Spinner } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { PatternDetails } from './pattern-details';
import classnames from 'classnames';
export default function PatternList( {
bulkInsertEnabled = false,
patterns = [],
closeModal,
globalStyleCSS,
globalStyleData,
readOnly = false,
} ) {
const ref = useRef();
const loadMoreRef = useRef();
const {
activePatternId,
loading,
itemsPerPage,
itemCount,
setItemCount,
scrollPosition,
selectedPatterns,
selectedPatternsDispatch,
} = useLibrary();
const activePattern = useMemo( () => {
const found = patterns.filter( ( pattern ) => ( pattern.id === activePatternId ) );
return found[ 0 ] || undefined;
}, [ activePatternId ] );
const hide = loading ? { opacity: 0 } : {};
const [ visiblePatterns, setVisiblePatterns ] = useState( [] );
const [ loadMore, setLoadMore ] = useState( false );
useEffect( () => {
setVisiblePatterns( patterns.slice( 0, itemCount ) );
}, [ itemCount, patterns ] );
/**
* Set up our infinite scroll.
*/
useEffect( () => {
const intersectionObserver = new IntersectionObserver(
( entries ) => {
entries.forEach( ( entry ) => {
if ( entry.isIntersecting ) {
setLoadMore( true );
}
} );
},
{
root: null,
rootMargin: '0px',
threshold: 0.01,
}
);
if ( loadMoreRef.current ) {
intersectionObserver.observe( loadMoreRef.current );
}
return () => {
if ( intersectionObserver ) {
intersectionObserver.disconnect();
}
};
}, [] );
/**
* Load more patterns when we reach the bottom.
*/
useEffect( () => {
if ( ! loadMore ) {
return;
}
if ( activePattern ) {
setLoadMore( false );
return;
}
setItemCount( itemCount + itemsPerPage );
setLoadMore( false );
}, [ loadMore ] );
/**
* Scroll to the last remembered scroll position.
* This is used to remember where we were if we preview a pattern and return to the list.
*/
useEffect( () => {
if ( ref.current && ! activePattern ) {
const patternContent = ref.current.closest( '.gb-pattern-library__content' );
if ( patternContent ) {
patternContent.scrollTop = scrollPosition;
}
}
}, [ scrollPosition, activePattern ] );
const PatternDetailsMemo = memo( PatternDetails );
return (
<>
{ loading && ! activePatternId &&
<div className="loading-library"><Spinner />
{ __( 'Loading library', 'generateblocks' ) }
</div>
}
{ ! loading && ! patterns.length && ! activePatternId &&
<div className="loading-library">
{ __( 'No patterns found.', 'generateblocks' ) }
</div>
}
{ !! activePattern &&
<Pattern
isLoading={ loading }
isActive={ true }
pattern={ activePattern }
globalStyleCSS={ globalStyleCSS }
/>
}
<ul
ref={ ref }
className={ classnames( 'patterns-wrapper', bulkInsertEnabled && 'gb-bulk-insert' ) }
style={ {
...hide,
display: !! activePattern ? 'none' : '',
} }
>
{ visiblePatterns.map( ( pattern ) => {
const isSelected = selectedPatterns.some( ( { id } ) => id === pattern.id ) ?? false;
return (
<li
key={ pattern.id }
className={ classnames( 'gb-pattern-wrapper', 'gb-selectable', isSelected && bulkInsertEnabled && 'is-selected' ) }
>
{ bulkInsertEnabled && (
<Button
className="gb-selectable__toggle"
label={ isSelected
? __( 'Deselect this pattern', 'generateblocks' )
: __( 'Select this pattern', 'generate-blocks' )
}
onClick={ ( e ) => {
e.stopPropagation();
const type = isSelected ? 'REMOVE' : 'ADD';
selectedPatternsDispatch( { type, pattern } );
} }
/>
) }
{ ( bulkInsertEnabled || isSelected ) && (
<Button
className="check"
onClick={ ( e ) => {
e.stopPropagation();
selectedPatternsDispatch( { type: 'REMOVE', pattern } );
} }
onBlur={ ( e ) => e.stopPropagation() }
tabIndex="-1"
>
<span className="media-modal-icon"></span>
<span className="screen-reader-text">
{ __( 'Deselect', 'generateblocks' ) }
</span>
</Button>
) }
<Pattern
isLoading={ loading }
pattern={ pattern }
globalStyleCSS={ globalStyleCSS }
/>
<PatternDetailsMemo
pattern={ pattern }
patternRef={ ref }
bulkInsertEnabled={ bulkInsertEnabled }
globalStyleData={ globalStyleData }
closeModal={ closeModal }
readOnly={ readOnly }
/>
</li>
);
} ) }
</ul>
<div
ref={ loadMoreRef }
style={ { marginTop: '10px' } }
className="gblocks-patterns-load-more"
/>
</>
);
}