Skip to content
50 changes: 28 additions & 22 deletions src/components/design-library-list/design-library-list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,18 @@ import { Tooltip } from '~stackable/components'
/**
* WordPress dependencies.
*/
import { forwardRef, useState } from '@wordpress/element'
import { useState, useRef } from '@wordpress/element'
import { Dashicon, Spinner } from '@wordpress/components'
import { __ } from '@wordpress/i18n'

const DesignLibraryListItem = forwardRef( ( props, ref ) => {
const DesignLibraryListItem = props => {
const {
label,
plan,
selectedNum = false,
selectedData = null,
previewSize,
previewProps,
selectedTab,
plan, label,
selectedNum,
selectedData,
isMultiSelectBusy,
shouldRender,
} = props

const presetMarks = usePresetControls( 'spacingSizes' )?.getPresetMarks() || null
Expand All @@ -41,31 +39,36 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {

const [ isLoading, setIsLoading ] = useState( true )

const { hostRef, shadowRoot } = useShadowRoot()
const { hostRef, shadowRoot } = useShadowRoot( shouldRender )

const ref = useRef( null )

const {
blocks, enableBackground,
shadowBodySizeRef, blocksForSubstitutionRef,
onClickDesign,
} = usePreviewRenderer(
previewProps, previewSize, plan, spacingSize,
selectedTab, selectedNum, selectedData,
ref, hostRef, shadowRoot, setIsLoading,
)
previewSize, cardHeight, onClickDesign,
updateShadowBodySize,
} = usePreviewRenderer( props, shouldRender, spacingSize,
ref, hostRef, shadowRoot, setIsLoading )

const {
onMouseOut, onMouseOver, onMouseDown,
} = useAutoScroll( hostRef, shadowBodySizeRef, selectedTab )

const getDesignPreviewSize = () => {
if ( ! shadowRoot || isLoading ) {
return 0
}

return selectedNum && selectedData ? selectedData.selectedPreviewSize.preview
: ( enableBackground ? previewSize.heightBackground : previewSize.heightNoBackground )
}

const getCardHeight = () => {
const key = props.enableBackground ? 'background' : 'noBackground'
return cardHeight?.[ key ] || ( props.selectedTab === 'pages' ? 413 : 250 )
}

if ( ! shouldRender && ! props.selectedNum ) {
return <div style={ { height: `${ getCardHeight() }px` } } />
}

const mainClasses = classnames( [
'ugb-design-library-item',
'ugb-design-library-item--toggle',
Expand Down Expand Up @@ -102,19 +105,22 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {
) }
{ isLoading && <div className="stk-spinner-container"><Spinner /></div> }
<div
className="stk-block-design__host-container"
className={ `stk-block-design__host-container ${ ! shadowRoot || isLoading ? 'stk-is-loading' : 'stk-show' }` }
style={ {
transform: `scale(${ selectedNum && selectedData ? selectedData.selectedPreviewSize.scale : previewSize?.scale })`,
transformOrigin: 'top left',
height: getDesignPreviewSize(),
} }
>
<div className="stk-block-design__host" ref={ hostRef }>
{ shadowRoot && ! isLoading && <DesignPreview
{ shadowRoot && <DesignPreview
blocks={ blocks }
shadowRoot={ shadowRoot }
selectedTab={ selectedTab }
designIndex={ props.designIndex }
onMouseDown={ onMouseDown }
updateShadowBodySize={ updateShadowBodySize }
setIsLoading={ setIsLoading }
/> }
</div>
</div>
Expand Down Expand Up @@ -155,7 +161,7 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {
</footer>
</button>
)
} )
}

DesignLibraryListItem.defaultProps = {
designId: '',
Expand Down
35 changes: 34 additions & 1 deletion src/components/design-library-list/design-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ export const DesignPreview = ( {
blocks = '',
shadowRoot,
selectedTab,
designIndex,
onMouseDown = NOOP,
updateShadowBodySize = NOOP,
setIsLoading,
} ) => {
const ref = useRef( null )
const wrapperRef = useRef( null )

const isDragging = useRef( false )
const lastY = useRef( 0 )
Expand Down Expand Up @@ -77,13 +81,42 @@ export const DesignPreview = ( {
'preview-pages': selectedTab === 'pages',
} )

useEffect( () => {
const wrapper = wrapperRef.current

if ( ! wrapper ) {
return
}

const ric = window.requestIdleCallback || window.requestAnimationFrame
const sanitizedHTML = safeHTML( blocks )

if ( selectedTab !== 'pages' || designIndex < 9 ) {
// insert HTML for patterns and for the first 9 pages
wrapper.innerHTML = sanitizedHTML
return
}

setIsLoading( true )

requestAnimationFrame( () => {
ric( () => {
wrapper.innerHTML = sanitizedHTML
updateShadowBodySize()
requestAnimationFrame( () => {
ric( () => setIsLoading( false ) )
} )
} )
} )
}, [ blocks ] )

return createPortal( <>
<body
ref={ ref }
className={ shadowBodyClasses }
>
<div
dangerouslySetInnerHTML={ { __html: safeHTML( blocks ) } }
ref={ wrapperRef }
style={ { pointerEvents: 'none' } } // prevent blocks from being clicked
/>
</body>
Expand Down
10 changes: 9 additions & 1 deletion src/components/design-library-list/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,14 @@

.stk-block-design__host-container {
position: relative;
transition: opacity 0.3s cubic-bezier(0.2, 0.6, 0.4, 1);
will-change: opacity;
&.stk-is-loading {
opacity: 0;
}
&.stk-show {
opacity: 1;
}
}

.stk--design-preview-large {
Expand Down Expand Up @@ -233,7 +241,7 @@
}

&.stk-design-library__item-pages .stk-spinner-container {
height: 400px;
height: 100%;
display: flex;
.components-spinner {
margin: auto;
Expand Down
70 changes: 20 additions & 50 deletions src/components/design-library-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const DesignLibraryList = props => {
onSelectMulti,
selectedDesigns = [],
selectedDesignData = [],
selectedTab,
} = props
const containerRef = useRef( null )

Expand Down Expand Up @@ -61,14 +62,14 @@ const DesignLibraryList = props => {

return (
<DesignLibraryItem
key={ i }
key={ design.id || design.designId }
plan={ design.plan }
label={ design.label || design.title }
previewProps={ previewProps }
selectedNum={ selectedNum }
selectedData={ selectedData }
selectedTab={ props.selectedTab }
designKey={ i }
selectedTab={ selectedTab }
designIndex={ i }
{ ...previewProps }
/>
)
} ) }
Expand All @@ -91,61 +92,30 @@ DesignLibraryList.defaultProps = {
export default DesignLibraryList

const DesignLibraryItem = props => {
const {
previewProps: _previewProps, ...propsToPass
} = props

const wrapperRef = useRef( null )
const itemRef = useRef( null )
const [ cardHeight, setCardHeight ] = useState( {} )
const [ previewSize, setPreviewSize ] = useState( {} )
const [ shouldRender, setShouldRender ] = useState( props.designKey < 9 )

const previewProps = {
..._previewProps,
setPreviewSize: previewSize => setPreviewSize( previewSize ),
setCardHeight: height => setCardHeight( height ),
cardHeight,
}
const [ shouldRender, setShouldRender ] = useState( false )

useEffect( () => {
const rootEl = document.querySelector( '.ugb-modal-design-library__designs' )
if ( ! wrapperRef.current || ! rootEl ) {
return
let id
if ( typeof requestIdleCallback !== 'undefined' ) {
id = requestIdleCallback( () => setShouldRender( true ) )
} else {
// fallback
id = setTimeout( () => setShouldRender( true ), 0 )
}

const observer = new IntersectionObserver( ( [ entry ] ) => {
// reduce flicker during rapid scrolls
requestAnimationFrame( () => {
requestAnimationFrame( () => setShouldRender( entry.isIntersecting ) )
} )
}, {
root: rootEl,
rootMargin: '500px',
threshold: 0,
} )

observer.observe( wrapperRef.current )
return () => observer.disconnect()
return () => {
if ( typeof cancelIdleCallback !== 'undefined' ) {
cancelIdleCallback( id )
} else {
clearTimeout( id )
}
}
}, [] )

const getCardHeight = () => {
const key = _previewProps.enableBackground ? 'background' : 'noBackground'
return props.selectedTab === 'pages' ? 472 : cardHeight?.[ key ] || 250
}

return (
<div ref={ wrapperRef }>
{ ! shouldRender && ! props.selectedNum ? (
<div ref={ itemRef } style={ { height: `${ getCardHeight() }px` } } />
) : (
<DesignLibraryListItem
ref={ itemRef }
previewSize={ previewSize }
previewProps={ previewProps }
{ ...propsToPass }
/>
) }
<DesignLibraryListItem { ...props } shouldRender={ shouldRender } />
</div>
)
}
Loading
Loading