Skip to content
40 changes: 24 additions & 16 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,17 +39,17 @@ 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,
Expand All @@ -66,6 +64,15 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {
: ( 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 @@ -115,6 +122,7 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {
shadowRoot={ shadowRoot }
selectedTab={ selectedTab }
onMouseDown={ onMouseDown }
updateShadowBodySize={ updateShadowBodySize }
/> }
</div>
</div>
Expand Down Expand Up @@ -155,7 +163,7 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {
</footer>
</button>
)
} )
}

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

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

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

if ( ! wrapper ) {
return
}

if ( selectedTab !== 'pages' ) {
wrapper.innerHTML = safeHTML( blocks )
}

requestAnimationFrame( () => {
requestIdleCallback( () => {
wrapper.innerHTML = safeHTML( blocks )
updateShadowBodySize()
} )
} )
}, [ 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
2 changes: 1 addition & 1 deletion src/components/design-library-list/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@
}

&.stk-design-library__item-pages .stk-spinner-container {
height: 400px;
height: 343px;
display: flex;
.components-spinner {
margin: auto;
Expand Down
71 changes: 20 additions & 51 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 All @@ -45,7 +46,7 @@ const DesignLibraryList = props => {
{ isBusy && <Spinner style={ { display: 'block', margin: '0 auto' } } /> }
{ ! isBusy && <>
<div className={ listClasses }>
{ ( designs || [] ).map( ( design, i ) => {
{ ( designs || [] ).map( design => {
const selectedNum = selectedDesigns.indexOf( design.id || design.designId ) + 1
const selectedData = selectedNum ? selectedDesignData[ selectedNum - 1 ] : null

Expand All @@ -61,14 +62,13 @@ 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 }
{ ...previewProps }
/>
)
} ) }
Expand All @@ -91,61 +91,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