Skip to content

Commit 7941d47

Browse files
ntsekourasrichtaboryouknowriadjasmussenjameskoster
authored
Iterate zoom out shuffle into a more visual control (WordPress#66194)
Co-authored-by: ntsekouras <[email protected]> Co-authored-by: richtabor <[email protected]> Co-authored-by: youknowriad <[email protected]> Co-authored-by: jasmussen <[email protected]> Co-authored-by: jameskoster <[email protected]> Co-authored-by: ellatrix <[email protected]> Co-authored-by: afercia <[email protected]>
1 parent 029716e commit 7941d47

File tree

4 files changed

+152
-119
lines changed

4 files changed

+152
-119
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import {
5+
ToolbarButton,
6+
ToolbarGroup,
7+
Dropdown,
8+
__experimentalDropdownContentWrapper as DropdownContentWrapper,
9+
} from '@wordpress/components';
10+
import { __ } from '@wordpress/i18n';
11+
import { cloneBlock } from '@wordpress/blocks';
12+
import { useMemo } from '@wordpress/element';
13+
import { useAsyncList } from '@wordpress/compose';
14+
import { useSelect, useDispatch } from '@wordpress/data';
15+
16+
/**
17+
* Internal dependencies
18+
*/
19+
import { store as blockEditorStore } from '../../store';
20+
import BlockPatternsList from '../block-patterns-list';
21+
22+
const EMPTY_ARRAY = [];
23+
const MAX_PATTERNS_TO_SHOW = 6;
24+
const POPOVER_PROPS = {
25+
placement: 'bottom-start',
26+
};
27+
28+
export default function ChangeDesign( { clientId } ) {
29+
const { categories, currentPatternName, patterns } = useSelect(
30+
( select ) => {
31+
const {
32+
getBlockAttributes,
33+
getBlockRootClientId,
34+
__experimentalGetAllowedPatterns,
35+
} = select( blockEditorStore );
36+
const attributes = getBlockAttributes( clientId );
37+
const _categories = attributes?.metadata?.categories || EMPTY_ARRAY;
38+
const rootBlock = getBlockRootClientId( clientId );
39+
40+
// Calling `__experimentalGetAllowedPatterns` is expensive.
41+
// Checking if the block can be changed prevents unnecessary selector calls.
42+
// See: https://github.com/WordPress/gutenberg/pull/64736.
43+
const _patterns =
44+
_categories.length > 0
45+
? __experimentalGetAllowedPatterns( rootBlock )
46+
: EMPTY_ARRAY;
47+
return {
48+
categories: _categories,
49+
currentPatternName: attributes?.metadata?.patternName,
50+
patterns: _patterns,
51+
};
52+
},
53+
[ clientId ]
54+
);
55+
const { replaceBlocks } = useDispatch( blockEditorStore );
56+
const sameCategoryPatternsWithSingleWrapper = useMemo( () => {
57+
if ( categories.length === 0 || ! patterns || patterns.length === 0 ) {
58+
return EMPTY_ARRAY;
59+
}
60+
return patterns
61+
.filter( ( pattern ) => {
62+
const isCorePattern =
63+
pattern.source === 'core' ||
64+
( pattern.source?.startsWith( 'pattern-directory' ) &&
65+
pattern.source !== 'pattern-directory/theme' );
66+
return (
67+
// Check if the pattern has only one top level block,
68+
// otherwise we may switch to a pattern that doesn't have replacement suggestions.
69+
pattern.blocks.length === 1 &&
70+
// We exclude the core patterns and pattern directory patterns that are not theme patterns.
71+
! isCorePattern &&
72+
// Exclude current pattern.
73+
currentPatternName !== pattern.name &&
74+
pattern.categories?.some( ( category ) => {
75+
return categories.includes( category );
76+
} ) &&
77+
// Check if the pattern is not a synced pattern.
78+
( pattern.syncStatus === 'unsynced' || ! pattern.id )
79+
);
80+
} )
81+
.slice( 0, MAX_PATTERNS_TO_SHOW );
82+
}, [ categories, currentPatternName, patterns ] );
83+
84+
const currentShownPatterns = useAsyncList(
85+
sameCategoryPatternsWithSingleWrapper
86+
);
87+
88+
if ( sameCategoryPatternsWithSingleWrapper.length < 2 ) {
89+
return null;
90+
}
91+
92+
const onClickPattern = ( pattern ) => {
93+
const newBlocks = ( pattern.blocks ?? [] ).map( ( block ) => {
94+
return cloneBlock( block );
95+
} );
96+
newBlocks[ 0 ].attributes.metadata = {
97+
...newBlocks[ 0 ].attributes.metadata,
98+
categories,
99+
};
100+
replaceBlocks( clientId, newBlocks );
101+
};
102+
103+
return (
104+
<Dropdown
105+
popoverProps={ POPOVER_PROPS }
106+
renderToggle={ ( { onToggle, isOpen } ) => {
107+
return (
108+
<ToolbarGroup>
109+
<ToolbarButton
110+
onClick={ () => onToggle( ! isOpen ) }
111+
aria-expanded={ isOpen }
112+
>
113+
{ __( 'Change design' ) }
114+
</ToolbarButton>
115+
</ToolbarGroup>
116+
);
117+
} }
118+
renderContent={ () => (
119+
<DropdownContentWrapper
120+
className="block-editor-block-toolbar-change-design-content-wrapper"
121+
paddingSize="none"
122+
>
123+
<BlockPatternsList
124+
shownPatterns={ currentShownPatterns }
125+
blockPatterns={ sameCategoryPatternsWithSingleWrapper }
126+
onClickPattern={ onClickPattern }
127+
showTitle={ false }
128+
/>
129+
</DropdownContentWrapper>
130+
) }
131+
/>
132+
);
133+
}

packages/block-editor/src/components/block-toolbar/index.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
isReusableBlock,
1717
isTemplatePart,
1818
} from '@wordpress/blocks';
19-
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
19+
import { ToolbarGroup } from '@wordpress/components';
2020

2121
/**
2222
* Internal dependencies
@@ -35,7 +35,7 @@ import { store as blockEditorStore } from '../../store';
3535
import __unstableBlockNameContext from './block-name-context';
3636
import NavigableToolbar from '../navigable-toolbar';
3737
import { useHasBlockToolbar } from './use-has-block-toolbar';
38-
import Shuffle from './shuffle';
38+
import ChangeDesign from './change-design';
3939
import { unlock } from '../../lock-unlock';
4040

4141
/**
@@ -220,12 +220,7 @@ export function PrivateBlockToolbar( {
220220
isMultiToolbar &&
221221
showGroupButtons && <BlockGroupToolbar /> }
222222
{ showShuffleButton && (
223-
<ToolbarGroup>
224-
<Shuffle
225-
clientId={ blockClientIds[ 0 ] }
226-
as={ ToolbarButton }
227-
/>
228-
</ToolbarGroup>
223+
<ChangeDesign clientId={ blockClientIds[ 0 ] } />
229224
) }
230225
{ shouldShowVisualToolbar && showSlots && (
231226
<>

packages/block-editor/src/components/block-toolbar/shuffle.js

Lines changed: 0 additions & 111 deletions
This file was deleted.

packages/block-editor/src/components/block-toolbar/style.scss

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,19 @@
285285
}
286286
}
287287
}
288+
289+
.block-editor-block-toolbar-change-design-content-wrapper {
290+
padding: $grid-unit-15;
291+
width: 320px;
292+
.block-editor-block-patterns-list {
293+
display: grid;
294+
grid-template-columns: 1fr 1fr;
295+
grid-gap: $grid-unit-15;
296+
.block-editor-block-patterns-list__list-item {
297+
margin-bottom: 0;
298+
}
299+
.block-editor-inserter__media-list__list-item {
300+
min-height: 100px;
301+
}
302+
}
303+
}

0 commit comments

Comments
 (0)