Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/components/design-library-list/design-library-list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,22 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {
const {
blocks, enableBackground,
shadowBodySizeRef, blocksForSubstitutionRef,
adjustScale, onClickDesign,
onClickDesign,
} = usePreviewRenderer(
previewProps, previewSize, plan, spacingSize,
selectedTab, selectedNum, selectedData,
ref, shadowRoot, setIsLoading
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 )
}
Expand Down Expand Up @@ -88,7 +92,7 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {
onMouseOver={ onMouseOver }
>
{ ! isPro && plan !== 'free' && <span className="stk-pulsating-circle" role="presentation" /> }
<div style={ { position: 'relative' } } className={ `${ getDesignPreviewSize() > 100 ? 'stk--design-preview-large' : 'stk--design-preview-small' }` }>
<div style={ { position: 'relative' } } className={ `stk-block-design__design-container ${ getDesignPreviewSize() > 100 ? 'stk--design-preview-large' : 'stk--design-preview-small' }` }>
{ ! isPro && plan !== 'free' && (
<ProControl
type="design-library"
Expand All @@ -106,11 +110,10 @@ const DesignLibraryListItem = forwardRef( ( props, ref ) => {
} }
>
<div className="stk-block-design__host" ref={ hostRef }>
{ shadowRoot && <DesignPreview
{ shadowRoot && ! isLoading && <DesignPreview
blocks={ blocks }
shadowRoot={ shadowRoot }
selectedTab={ selectedTab }
adjustScale={ adjustScale }
onMouseDown={ onMouseDown }
/> }
</div>
Expand Down
6 changes: 0 additions & 6 deletions src/components/design-library-list/design-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export const DesignPreview = ( {
blocks = '',
shadowRoot,
selectedTab,
adjustScale = NOOP,
onMouseDown = NOOP,
} ) => {
const ref = useRef( null )
Expand Down Expand Up @@ -72,11 +71,6 @@ export const DesignPreview = ( {
}
}, [ selectedTab ] )

useEffect( () => {
// The scale might not be correct on first load, so adjust it again to be sure.
setTimeout( adjustScale, 100 )
}, [] )

const shadowBodyClasses = classnames( applyFilters( 'stackable.global-styles.classnames', [
'entry-content',
] ), {
Expand Down
1 change: 1 addition & 0 deletions src/components/design-library-list/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
background: #f4f4f5;
}
.ugb-design-library-item {
width: 100%;
display: grid;
grid-template-columns: 1fr;
padding: 0;
Expand Down
73 changes: 34 additions & 39 deletions src/components/design-library-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ const DesignLibraryList = props => {
} = props
const containerRef = useRef( null )

const [ scrollTop, setScrollTop ] = useState( 0 )

const listClasses = classnames( [
'ugb-design-library-items',
className,
Expand All @@ -43,9 +41,6 @@ const DesignLibraryList = props => {
return <div
className="ugb-modal-design-library__designs"
ref={ containerRef }
onScroll={ e => {
setScrollTop( e.currentTarget.scrollTop )
} }
>
{ isBusy && <Spinner style={ { display: 'block', margin: '0 auto' } } /> }
{ ! isBusy && <>
Expand Down Expand Up @@ -73,7 +68,6 @@ const DesignLibraryList = props => {
selectedNum={ selectedNum }
selectedData={ selectedData }
selectedTab={ props.selectedTab }
scrollTop={ scrollTop }
designKey={ i }
/>
)
Expand All @@ -98,9 +92,10 @@ export default DesignLibraryList

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

const wrapperRef = useRef( null )
const itemRef = useRef( null )
const [ cardHeight, setCardHeight ] = useState( {} )
const [ previewSize, setPreviewSize ] = useState( {} )
Expand All @@ -114,43 +109,43 @@ const DesignLibraryItem = props => {
}

useEffect( () => {
// Use a timeout to ensure designs have finished rendering before calculating visibility.
const timeoutRef = setTimeout( () => {
const itemEl = itemRef.current
const containerEl = itemEl?.closest( '.ugb-modal-design-library__designs' ) || document.querySelector( '.ugb-modal-design-library__designs' )

if ( ! itemEl || ! containerEl ) {
return
}

const containerRect = containerEl.getBoundingClientRect()
const itemRect = itemEl.getBoundingClientRect()

const BOUNDARY = 250

const render = itemRect.bottom >= containerRect.top - BOUNDARY && itemRect.top <= containerRect.bottom + BOUNDARY

setShouldRender( render )
}, 250 )

return () => {
clearTimeout( timeoutRef )
const rootEl = document.querySelector( '.ugb-modal-design-library__designs' )
if ( ! wrapperRef.current || ! rootEl ) {
return
}
}, [ scrollTop, _previewProps.enableBackground, _previewProps.designId ] )

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()
}, [] )

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

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

return <DesignLibraryListItem
ref={ itemRef }
previewSize={ previewSize }
previewProps={ previewProps }
{ ...propsToPass }
/>
return (
<div ref={ wrapperRef }>
{ ! shouldRender && ! props.selectedNum ? (
<div ref={ itemRef } style={ { height: `${ getCardHeight() }px` } } />
) : (
<DesignLibraryListItem
ref={ itemRef }
previewSize={ previewSize }
previewProps={ previewProps }
{ ...propsToPass }
/>
) }
</div>
)
}
129 changes: 87 additions & 42 deletions src/components/design-library-list/use-preview-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const DEFAULT_CONTENT = { ...DEFAULT }
export const usePreviewRenderer = (
props, previewSize, plan, spacingSize,
selectedTab, selectedNum, selectedData,
ref, shadowRoot, setIsLoading
ref, hostRef, shadowRoot, setIsLoading
) => {
const {
designId,
Expand All @@ -61,64 +61,89 @@ export const usePreviewRenderer = (
const hasBackgroundTargetRef = useRef( false )
const initialRenderRef = useRef( null )
const shadowBodySizeRef = useRef( null )
const prevEnableBackgroundRef = useRef( false )
const prevEnableBackgroundRef = useRef( null )
const prevSelectedTabRef = useRef( selectedTab )
const adjustAnimateFrameRef = useRef( null )

const siteTitle = useSelect( select => select( 'core' ).getEntityRecord( 'root', 'site' )?.title || 'InnovateCo', [] )
const isDesignLibraryDevMode = devMode && localStorage.getItem( 'stk__design_library__dev_mode' ) === '1'

const addHasBackground = selectedTab === 'patterns'

const adjustScale = () => {
const shouldAdjust = ref.current && shadowRoot &&
const adjustScale = ( force = true ) => {
const parentDiv = ref?.current?.querySelector( '.stk-block-design__design-container' )
const shouldAdjust = ref.current && hostRef.current && shadowRoot && parentDiv &&
( ! selectedNum || // adjust if design is not selected
prevSelectedTabRef.current !== selectedTab ) // adjust if selected tab changed even if design is selected

if ( shouldAdjust ) {
const newPreviewSize = { ...previewSize }
const newCardHeight = { ...cardHeight }
const cardRect = ref.current.getBoundingClientRect()
if ( ! shouldAdjust ) {
return
}
const newPreviewSize = { ...previewSize }
const newCardHeight = { ...cardHeight }

const shadowBody = shadowRoot.querySelector( 'body' )
if ( shadowBody ) {
const cardWidth = cardRect.width // Get width of the card
const scaleFactor = cardWidth > 0 ? cardWidth / 1300 : 1 // Divide by 1300, which is the width of preview in the shadow DOM
newPreviewSize.scale = scaleFactor
const cardRect = ref.current.getBoundingClientRect()
const hostRect = hostRef.current.getBoundingClientRect()
const parentDivRect = parentDiv.getBoundingClientRect()

let _bodyHeight = 1200
if ( selectedTab === 'patterns' ) {
_bodyHeight = shadowBody.offsetHeight
}
const cardWidth = cardRect.width
const hostWidth = hostRect.width

const _height = parseFloat( _bodyHeight ) * scaleFactor // Also adjust the height
// Consider heights equal if the difference is less than 1px
const isEqualHeight = Math.abs( parentDivRect.height - hostRect.height ) < 1

if ( Object.keys( newPreviewSize ).length === 1 ) {
newPreviewSize.heightBackground = _height
newPreviewSize.heightNoBackground = _height
} else {
const heightKey = enableBackground ? 'heightBackground' : 'heightNoBackground'
newPreviewSize[ heightKey ] = _height
}
if ( ! force && cardWidth === hostWidth && isEqualHeight ) {
if ( adjustAnimateFrameRef.current !== null ) {
cancelAnimationFrame( adjustAnimateFrameRef.current )
}
adjustAnimateFrameRef.current = null
return
}

setPreviewSize( newPreviewSize )
const shadowBody = shadowRoot.querySelector( 'body' )
if ( shadowBody ) {
const cardWidth = cardRect.width // Get width of the card
const scaleFactor = cardWidth > 0 ? cardWidth / 1300 : 1 // Divide by 1300, which is the width of preview in the shadow DOM
newPreviewSize.scale = scaleFactor

shadowBodySizeRef.current = {
clientHeight: shadowBody.clientHeight,
scrollHeight: shadowBody.scrollHeight,
maxScrollTop: shadowBody.scrollHeight - shadowBody.clientHeight,
}
let _bodyHeight = 1200
if ( selectedTab === 'patterns' ) {
_bodyHeight = shadowBody.offsetHeight
}

if ( ! Object.keys( newCardHeight ).length ) {
newCardHeight.background = cardRect.height
newCardHeight.noBackground = cardRect.height
const _height = parseFloat( _bodyHeight ) * scaleFactor // Also adjust the height

if ( Object.keys( newPreviewSize ).length === 1 ) {
newPreviewSize.heightBackground = _height
newPreviewSize.heightNoBackground = _height
} else {
const CardHeightKey = enableBackground ? 'background' : 'noBackground'
newCardHeight[ CardHeightKey ] = cardRect.height
const heightKey = enableBackground ? 'heightBackground' : 'heightNoBackground'
newPreviewSize[ heightKey ] = _height
}

setPreviewSize( newPreviewSize )

shadowBodySizeRef.current = {
clientHeight: shadowBody.clientHeight,
scrollHeight: shadowBody.scrollHeight,
maxScrollTop: shadowBody.scrollHeight - shadowBody.clientHeight,
}
}

if ( ! Object.keys( newCardHeight ).length ) {
newCardHeight.background = cardRect.height
newCardHeight.noBackground = cardRect.height
} else {
const CardHeightKey = enableBackground ? 'background' : 'noBackground'
newCardHeight[ CardHeightKey ] = cardRect.height
}

setTimeout( () => setCardHeight( newCardHeight ), 500 )

setTimeout( () => setCardHeight( newCardHeight ), 500 )
if ( adjustAnimateFrameRef.current !== null ) {
cancelAnimationFrame( adjustAnimateFrameRef.current )
}
adjustAnimateFrameRef.current = requestAnimationFrame( () => adjustScale( false ) )
}

const renderPreview = ( blockContent = content ) => {
Expand Down Expand Up @@ -274,7 +299,10 @@ export const usePreviewRenderer = (
useEffect( () => {
if ( selectedNum === 0 && content && shadowRoot ) {
renderPreview()
setTimeout( adjustScale, 100 )
if ( adjustAnimateFrameRef.current !== null ) {
cancelAnimationFrame( adjustAnimateFrameRef.current )
}
adjustAnimateFrameRef.current = requestAnimationFrame( adjustScale )
}
}, [ selectedNum ] )

Expand All @@ -285,7 +313,11 @@ export const usePreviewRenderer = (

if ( prevEnableBackgroundRef.current !== enableBackground ) {
prevEnableBackgroundRef.current = enableBackground
adjustScale()

if ( adjustAnimateFrameRef.current !== null ) {
cancelAnimationFrame( adjustAnimateFrameRef.current )
}
adjustAnimateFrameRef.current = requestAnimationFrame( adjustScale )
}
}, [ blocks ] )

Expand All @@ -294,12 +326,25 @@ export const usePreviewRenderer = (
if ( ! content || ! blocks.parsed || ! blocks.serialized ) {
return
}
setTimeout( () => {

if ( adjustAnimateFrameRef.current !== null ) {
cancelAnimationFrame( adjustAnimateFrameRef.current )
}

adjustAnimateFrameRef.current = requestAnimationFrame( () => {
adjustScale()
prevSelectedTabRef.current = selectedTab
}, 100 )
} )
}, [ content ] )

// cleanup any pending animation on unmount
useEffect( () => {
return () => {
cancelAnimationFrame( adjustAnimateFrameRef.current )
adjustAnimateFrameRef.current = null
}
}, [] )

const onClickDesign = () => {
if ( ! isPro && plan !== 'free' ) {
return
Expand All @@ -319,6 +364,6 @@ export const usePreviewRenderer = (
return {
blocks: blocks.serialized, enableBackground,
shadowBodySizeRef, blocksForSubstitutionRef,
adjustScale, onClickDesign,
onClickDesign,
}
}
3 changes: 3 additions & 0 deletions src/components/modal-design-library/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@

&.ugb-modal-design-library__full-pages {
grid-template-rows: auto auto;
.ugb-modal-design-library__designs {
grid-row: 1 / -1;
}
}
}
.ugb-modal-design-library__sidebar {
Expand Down
Loading