Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterate zoom out shuffle into a more visual control #66194

Merged
merged 5 commits into from
Oct 25, 2024
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
133 changes: 133 additions & 0 deletions packages/block-editor/src/components/block-toolbar/change-design.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/**
* WordPress dependencies
*/
import {
ToolbarButton,
ToolbarGroup,
Dropdown,
__experimentalDropdownContentWrapper as DropdownContentWrapper,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { cloneBlock } from '@wordpress/blocks';
import { useMemo } from '@wordpress/element';
import { useAsyncList } from '@wordpress/compose';
import { useSelect, useDispatch } from '@wordpress/data';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import BlockPatternsList from '../block-patterns-list';

const EMPTY_ARRAY = [];
const MAX_PATTERNS_TO_SHOW = 6;
const POPOVER_PROPS = {
placement: 'bottom-start',
};

export default function ChangeDesign( { clientId } ) {
const { categories, currentPatternName, patterns } = useSelect(
( select ) => {
const {
getBlockAttributes,
getBlockRootClientId,
__experimentalGetAllowedPatterns,
} = select( blockEditorStore );
const attributes = getBlockAttributes( clientId );
const _categories = attributes?.metadata?.categories || EMPTY_ARRAY;
const rootBlock = getBlockRootClientId( clientId );

// Calling `__experimentalGetAllowedPatterns` is expensive.
// Checking if the block can be changed prevents unnecessary selector calls.
// See: https://github.com/WordPress/gutenberg/pull/64736.
const _patterns =
_categories.length > 0
? __experimentalGetAllowedPatterns( rootBlock )
: EMPTY_ARRAY;
return {
categories: _categories,
currentPatternName: attributes?.metadata?.patternName,
patterns: _patterns,
};
},
[ clientId ]
);
const { replaceBlocks } = useDispatch( blockEditorStore );
const sameCategoryPatternsWithSingleWrapper = useMemo( () => {
if ( categories.length === 0 || ! patterns || patterns.length === 0 ) {
return EMPTY_ARRAY;
}
return patterns
.filter( ( pattern ) => {
const isCorePattern =
pattern.source === 'core' ||
( pattern.source?.startsWith( 'pattern-directory' ) &&
pattern.source !== 'pattern-directory/theme' );
return (
// Check if the pattern has only one top level block,
// otherwise we may switch to a pattern that doesn't have replacement suggestions.
pattern.blocks.length === 1 &&
// We exclude the core patterns and pattern directory patterns that are not theme patterns.
! isCorePattern &&
// Exclude current pattern.
currentPatternName !== pattern.name &&
pattern.categories?.some( ( category ) => {
return categories.includes( category );
} ) &&
// Check if the pattern is not a synced pattern.
( pattern.syncStatus === 'unsynced' || ! pattern.id )
);
} )
.slice( 0, MAX_PATTERNS_TO_SHOW );
}, [ categories, currentPatternName, patterns ] );

const currentShownPatterns = useAsyncList(
sameCategoryPatternsWithSingleWrapper
);

if ( sameCategoryPatternsWithSingleWrapper.length < 2 ) {
return null;
}

const onClickPattern = ( pattern ) => {
const newBlocks = ( pattern.blocks ?? [] ).map( ( block ) => {
return cloneBlock( block );
} );
newBlocks[ 0 ].attributes.metadata = {
...newBlocks[ 0 ].attributes.metadata,
categories,
};
replaceBlocks( clientId, newBlocks );
};

return (
<Dropdown
popoverProps={ POPOVER_PROPS }
renderToggle={ ( { onToggle, isOpen } ) => {
return (
<ToolbarGroup>
<ToolbarButton
onClick={ () => onToggle( ! isOpen ) }
aria-expanded={ isOpen }
>
{ __( 'Change design' ) }
</ToolbarButton>
</ToolbarGroup>
);
} }
renderContent={ () => (
<DropdownContentWrapper
className="block-editor-block-toolbar-change-design-content-wrapper"
paddingSize="none"
>
<BlockPatternsList
shownPatterns={ currentShownPatterns }
blockPatterns={ sameCategoryPatternsWithSingleWrapper }
onClickPattern={ onClickPattern }
showTitle={ false }
/>
</DropdownContentWrapper>
) }
/>
);
}
11 changes: 3 additions & 8 deletions packages/block-editor/src/components/block-toolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
isReusableBlock,
isTemplatePart,
} from '@wordpress/blocks';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { ToolbarGroup } from '@wordpress/components';

/**
* Internal dependencies
Expand All @@ -35,7 +35,7 @@ import { store as blockEditorStore } from '../../store';
import __unstableBlockNameContext from './block-name-context';
import NavigableToolbar from '../navigable-toolbar';
import { useHasBlockToolbar } from './use-has-block-toolbar';
import Shuffle from './shuffle';
import ChangeDesign from './change-design';
import { unlock } from '../../lock-unlock';

/**
Expand Down Expand Up @@ -211,12 +211,7 @@ export function PrivateBlockToolbar( {
shouldShowVisualToolbar &&
isMultiToolbar && <BlockGroupToolbar /> }
{ showShuffleButton && (
<ToolbarGroup>
<Shuffle
clientId={ blockClientIds[ 0 ] }
as={ ToolbarButton }
/>
</ToolbarGroup>
<ChangeDesign clientId={ blockClientIds[ 0 ] } />
) }
{ shouldShowVisualToolbar && (
<>
Expand Down
111 changes: 0 additions & 111 deletions packages/block-editor/src/components/block-toolbar/shuffle.js

This file was deleted.

16 changes: 16 additions & 0 deletions packages/block-editor/src/components/block-toolbar/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,19 @@
}
}
}

.block-editor-block-toolbar-change-design-content-wrapper {
padding: $grid-unit-15;
width: 320px;
.block-editor-block-patterns-list {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's your current thoughts about absorbing this into the component with variant="grid" or something. How feasible...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's doable (regarding the current usages and wrappers etc..). It's on my list to do this and see to consolidate the similar replace lists.

display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: $grid-unit-15;
.block-editor-block-patterns-list__list-item {
margin-bottom: 0;
}
.block-editor-inserter__media-list__list-item {
min-height: 100px;
}
}
}
Loading