Skip to content

Commit f854eab

Browse files
authored
Fix (design library): improve selecting of patterns (#3602)
* improve selection of patterns * update classname * fix coderabbit's qa
1 parent 1f652ed commit f854eab

File tree

5 files changed

+427
-322
lines changed

5 files changed

+427
-322
lines changed

src/components/design-library-list/design-library-list-item.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ import { __ } from '@wordpress/i18n'
2626

2727
const DesignLibraryListItem = memo( props => {
2828
const {
29-
selectedTab,
30-
plan, label,
31-
selectedNum,
32-
selectedData,
33-
isMultiSelectBusy,
3429
shouldRender,
3530
presetMarks,
31+
previewProps,
32+
isMultiSelectBusy,
3633
} = props
3734

35+
const {
36+
selectedTab, selectedNum, selectedData, plan, label,
37+
} = previewProps
38+
3839
const spacingSize = Array.isArray( presetMarks ) && presetMarks.length >= 2
3940
? presetMarks[ presetMarks.length - 2 ].value
4041
: 120
@@ -50,7 +51,7 @@ const DesignLibraryListItem = memo( props => {
5051
shadowBodySizeRef, blocksForSubstitutionRef,
5152
previewSize, onClickDesign,
5253
updateShadowBodySize,
53-
} = usePreviewRenderer( props, shouldRender, spacingSize,
54+
} = usePreviewRenderer( previewProps, shouldRender, spacingSize,
5455
ref, hostRef, shadowRoot, setIsLoading )
5556

5657
const {
@@ -76,6 +77,7 @@ const DesignLibraryListItem = memo( props => {
7677
], {
7778
[ `ugb--is-${ plan }` ]: ! isPro && plan !== 'free',
7879
'ugb--is-toggled': selectedNum,
80+
'ugb--is-hidden': ! shouldRender,
7981
} )
8082

8183
const onClickHost = e => {

src/components/design-library-list/editor.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
// box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
4343
border: 1px solid #0000001a;
4444
box-shadow: none;
45+
opacity: 1;
46+
will-change: opacity;
4547
.ugb-button-component {
4648
transition: opacity 0.4s cubic-bezier(0.2, 0.6, 0.4, 1);
4749
opacity: 0;
@@ -56,6 +58,11 @@
5658
opacity: 1;
5759
}
5860
}
61+
&.ugb--is-hidden {
62+
opacity: 0;
63+
pointer-events: none;
64+
visibility: hidden;
65+
}
5966
footer {
6067
line-height: 18px;
6168
background-color: #fff;

src/components/design-library-list/index.js

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,13 @@ import {
1818
useState, useEffect, useRef, memo, useMemo,
1919
} from '@wordpress/element'
2020
import { usePresetControls } from '~stackable/hooks'
21+
import { useDesignLibraryContext } from '../modal-design-library/modal'
2122

2223
const DesignLibraryList = memo( props => {
2324
const {
2425
className = '',
2526
designs,
2627
isBusy,
27-
onSelectMulti,
28-
selectedDesigns = [],
29-
selectedDesignData = [],
30-
selectedTab,
3128
} = props
3229
const containerRef = useRef( null )
3330

@@ -48,29 +45,11 @@ const DesignLibraryList = memo( props => {
4845
{ ! isBusy && <>
4946
<div className={ listClasses }>
5047
{ ( designs || [] ).map( ( design, i ) => {
51-
const selectedNum = selectedDesigns.indexOf( design.id || design.designId ) + 1
52-
const selectedData = selectedNum ? selectedDesignData[ selectedNum - 1 ] : null
53-
54-
const previewProps = {
55-
designId: design.id || design.designId,
56-
template: design.template || design.content,
57-
category: design.category,
58-
containerScheme: props.containerScheme,
59-
backgroundScheme: props.backgroundScheme,
60-
enableBackground: props.enableBackground,
61-
onClick: onSelectMulti,
62-
}
63-
6448
return (
6549
<DesignLibraryItem
50+
design={ design }
6651
key={ design.id || design.designId }
67-
plan={ design.plan }
68-
label={ design.label || design.title }
69-
selectedNum={ selectedNum }
70-
selectedData={ selectedData }
71-
selectedTab={ selectedTab }
7252
designIndex={ i }
73-
{ ...previewProps }
7453
/>
7554
)
7655
} ) }
@@ -92,10 +71,53 @@ DesignLibraryList.defaultProps = {
9271

9372
export default DesignLibraryList
9473

95-
const DesignLibraryItem = props => {
96-
const { selectedTab, designIndex } = props
74+
const DesignLibraryItem = memo( props => {
75+
const { design, designIndex } = props
9776
const wrapperRef = useRef( null )
9877
const [ shouldRender, setShouldRender ] = useState( designIndex < 9 )
78+
79+
const [ selectedTab,
80+
selectedDesignIds,
81+
selectedDesignData,
82+
onSelectDesign,
83+
isMultiSelectBusy,
84+
containerScheme,
85+
backgroundScheme,
86+
enableBackground,
87+
] = useDesignLibraryContext()
88+
89+
const { selectedNum, selectedData } = useMemo( () => {
90+
const selectedNum = selectedDesignIds.indexOf( design.id || design.designId ) + 1
91+
const selectedData = selectedNum ? selectedDesignData[ selectedNum - 1 ] : null
92+
93+
return { selectedNum, selectedData }
94+
}, [ selectedDesignIds, selectedDesignData ] )
95+
96+
const previewProps = useMemo( () => ( {
97+
designId: design.id || design.designId,
98+
template: design.template || design.content,
99+
category: design.category,
100+
plan: design.plan,
101+
label: design.label,
102+
containerScheme,
103+
backgroundScheme,
104+
enableBackground: selectedTab !== 'pages' ? enableBackground : true,
105+
selectedTab,
106+
selectedNum,
107+
selectedData,
108+
onClick: onSelectDesign,
109+
} ), [
110+
// Only track designId for memoization; other design properties will update when designId changes
111+
design.id || design.designId,
112+
containerScheme,
113+
backgroundScheme,
114+
enableBackground,
115+
selectedTab,
116+
// selectedNum and selectedData are always in sync; updating selectedNum also updates selectedData
117+
selectedNum,
118+
onSelectDesign,
119+
] )
120+
99121
const { getPresetMarks } = usePresetControls( 'spacingSizes' )
100122

101123
// Intentionally no dependencies: presetMarks won't change while the design library is open
@@ -135,7 +157,7 @@ const DesignLibraryItem = props => {
135157
const observer = new IntersectionObserver( ( [ entry ] ) => {
136158
// reduce flicker during rapid scrolls
137159
requestAnimationFrame( () => {
138-
requestAnimationFrame( () => setShouldRender( entry.isIntersecting ) )
160+
requestAnimationFrame( () => setShouldRender( entry.isIntersecting || entry.intersectionRatio > 0 ) )
139161
} )
140162
}, {
141163
root: rootEl,
@@ -151,7 +173,11 @@ const DesignLibraryItem = props => {
151173

152174
return (
153175
<div ref={ wrapperRef }>
154-
<DesignLibraryListItem { ...props } shouldRender={ shouldRender } presetMarks={ presetMarks } />
176+
<DesignLibraryListItem
177+
previewProps={ previewProps }
178+
isMultiSelectBusy={ isMultiSelectBusy }
179+
shouldRender={ shouldRender }
180+
presetMarks={ presetMarks } />
155181
</div>
156182
)
157-
}
183+
} )
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
2+
import AdvancedToolbarControl from '../advanced-toolbar-control'
3+
import Button from '../button'
4+
/**
5+
* External deprendencies
6+
*/
7+
import {
8+
i18n, isPro, devMode,
9+
} from 'stackable'
10+
11+
/**
12+
* WordPress deprendencies
13+
*/
14+
import {
15+
Dashicon,
16+
Dropdown,
17+
ToggleControl,
18+
} from '@wordpress/components'
19+
20+
import { __ } from '@wordpress/i18n'
21+
22+
export const PLAN_OPTIONS = [ { key: '', label: __( 'All', i18n ) }, { key: 'free', label: __( 'Free', i18n ) }, { key: 'premium', label: __( 'Premium', i18n ) } ]
23+
24+
export const HeaderActions = props => {
25+
const {
26+
selectedTab,
27+
setSelectedTab,
28+
selectedPlan,
29+
setSelectedPlan,
30+
setDoReset,
31+
onClose,
32+
} = props
33+
return <>
34+
{ /* DEV NOTE: hide for now */ }
35+
<AdvancedToolbarControl
36+
className="stk-design-library-tabs"
37+
fullwidth={ false }
38+
controls={ [
39+
{
40+
value: 'patterns',
41+
title: __( 'Patterns', i18n ),
42+
},
43+
{
44+
value: 'pages',
45+
title: __( 'Pages', i18n ),
46+
},
47+
] }
48+
value={ selectedTab }
49+
onChange={ setSelectedTab }
50+
isToggleOnly={ true }
51+
allowReset={ false }
52+
/>
53+
54+
<div className="stk-design-library__header-settings">
55+
{ devMode && (
56+
<ToggleControl
57+
label="Dev Mode"
58+
checked={ !! localStorage.getItem( 'stk__design_library__dev_mode' ) || false }
59+
onChange={ value => {
60+
localStorage.setItem( 'stk__design_library__dev_mode', value ? '1' : '' )
61+
setTimeout( () => {
62+
document?.querySelector( '.ugb-insert-library-button__wrapper .ugb-insert-library-button' )?.click()
63+
}, 100 )
64+
onClose()
65+
} }
66+
__nextHasNoMarginBottom
67+
/>
68+
) }
69+
<Button
70+
icon="image-rotate"
71+
iconSize={ 14 }
72+
label={ __( 'Refresh Library', i18n ) }
73+
className="ugb-modal-design-library__refresh"
74+
onClick={ () => setDoReset( true ) }
75+
/>
76+
{ ! isPro && <Dropdown
77+
focusOnMount="container"
78+
renderToggle={ ( { onToggle } ) => (
79+
<Button
80+
onClick={ onToggle }
81+
style={ { height: 'auto' } }
82+
icon="arrow-down-alt2"
83+
iconSize={ 12 }
84+
iconPosition="right"
85+
variant="secondary"
86+
>
87+
<Dashicon icon="lock" size={ 12 } />
88+
<span>{ selectedPlan.label }</span>
89+
</Button>
90+
) }
91+
renderContent={ ( { onClose } ) => (
92+
<div className="stk-design-library__plan-dropdown">
93+
{ PLAN_OPTIONS.map( ( plan, i ) => {
94+
return <Button
95+
key={ i }
96+
onClick={ () => {
97+
setSelectedPlan( plan )
98+
onClose()
99+
} }
100+
>
101+
{ plan.label }
102+
</Button>
103+
} ) }
104+
</div>
105+
) }
106+
/> }
107+
</div>
108+
</>
109+
}

0 commit comments

Comments
 (0)