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

Zoom out: try pattern inserter instead of starter pattern modal for new pages #61489

Closed
wants to merge 9 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { useSelect } from '@wordpress/data';
import PatternsExplorerModal from '../block-patterns-explorer';
import MobileTabNavigation from '../mobile-tab-navigation';
import { PatternCategoryPreviews } from './pattern-category-previews';
import { usePatternCategories } from './use-pattern-categories';
import CategoryTabs from '../category-tabs';
import InserterNoResults from '../no-results';
import { store as blockEditorStore } from '../../../store';
Expand All @@ -22,14 +21,12 @@ import { unlock } from '../../../lock-unlock';
function BlockPatternsTab( {
onSelectCategory,
selectedCategory,
categories,
onInsert,
rootClientId,
children,
} ) {
const [ showPatternsExplorer, setShowPatternsExplorer ] = useState( false );

const categories = usePatternCategories( rootClientId );

const isMobile = useViewportMatch( 'medium', '<' );
const isResolvingPatterns = useSelect(
( select ) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
isPatternFiltered,
allPatternsCategory,
myPatternsCategory,
starterContentCategory,
INSERTER_PATTERN_TYPES,
} from './utils';

Expand Down Expand Up @@ -67,6 +68,15 @@ export function usePatternCategories( rootClientId, sourceFilter = 'all' ) {
label: _x( 'Uncategorized' ),
} );
}

if (
patterns.find( ( pattern ) =>
pattern.categories.includes( 'core/content' )
)
) {
categories.unshift( starterContentCategory );
}

if (
filteredPatterns.some(
( pattern ) => pattern.type === INSERTER_PATTERN_TYPES.user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ export const allPatternsCategory = {

export const myPatternsCategory = {
name: 'myPatterns',
label: __( 'My patterns' ),
label: __( 'My Patterns' ),
};

export const starterContentCategory = {
name: 'core/content',
label: __( 'Starter Content' ),
};

export function isPatternFiltered( pattern, sourceFilter, syncFilter ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ import { store as noticesStore } from '@wordpress/notices';
import { store as blockEditorStore } from '../../../store';
import { INSERTER_PATTERN_TYPES } from '../block-patterns-tab/utils';

function useStartPatterns() {
// A pattern is a start pattern if it includes 'core/post-content' in its blockTypes,
// and it has no postTypes declared and the current post type is page or if
// the current post type is part of the postTypes declared.
return useSelect( ( select ) =>
select( blockEditorStore ).getPatternsByBlockTypes(
'core/post-content'
)
);
}

/**
* Retrieves the block patterns inserter state.
*
Expand Down Expand Up @@ -40,6 +51,29 @@ const usePatternsState = ( onInsert, rootClientId, selectedCategory ) => {
[ rootClientId ]
);

const starterPatterns = useStartPatterns();
const starterPatternsNames = starterPatterns.map(
( pattern ) => pattern.name
);
const newPatterns = useMemo(
() =>
patterns.map( ( pattern ) => {
if ( starterPatternsNames.includes( pattern.name ) ) {
// TODO - I'm not sure why we can't just use the pattern?
return {
...pattern,
categories: [
...( pattern.categories ?? [] ),
'core/content',
],
};
}

return pattern;
} ),
[ patterns, starterPatterns ]
);

const allCategories = useMemo( () => {
const categories = [ ...patternCategories ];
userPatternCategories?.forEach( ( userCategory ) => {
Expand Down Expand Up @@ -94,7 +128,7 @@ const usePatternsState = ( onInsert, rootClientId, selectedCategory ) => {
[ createSuccessNotice, onInsert, selectedCategory ]
);

return [ patterns, allCategories, onClickPattern ];
return [ newPatterns, allCategories, onClickPattern ];
};

export default usePatternsState;
9 changes: 8 additions & 1 deletion packages/block-editor/src/components/inserter/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import InserterSearchResults from './search-results';
import useInsertionPoint from './hooks/use-insertion-point';
import { store as blockEditorStore } from '../../store';
import TabbedSidebar from '../tabbed-sidebar';
import { useZoomOut } from '../../hooks/use-zoom-out';
import { usePatternCategories } from './block-patterns-tab/use-pattern-categories';
import { unlock } from '../../lock-unlock';

const NOOP = () => {};
function InserterMenu(
Expand Down Expand Up @@ -60,8 +63,11 @@ function InserterMenu(
const [ filterValue, setFilterValue, delayedFilterValue ] =
useDebouncedInput( __experimentalFilterValue );
const [ hoveredItem, setHoveredItem ] = useState( null );
const categories = usePatternCategories( rootClientId );
const [ selectedPatternCategory, setSelectedPatternCategory ] = useState(
__experimentalInitialCategory
categories.find(
( category ) => category.name === __experimentalInitialCategory
)
);
const [ patternFilter, setPatternFilter ] = useState( 'all' );
const [ selectedMediaCategory, setSelectedMediaCategory ] =
Expand Down Expand Up @@ -237,6 +243,7 @@ function InserterMenu(
onInsert={ onInsertPattern }
onSelectCategory={ onClickPatternCategory }
selectedCategory={ selectedPatternCategory }
categories={ categories }
>
{ showPatternPanel && (
<PatternCategoryPreviews
Expand Down
27 changes: 22 additions & 5 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2426,10 +2426,23 @@ export const getPatternsByBlockTypes = createRegistrySelector( ( select ) =>
if ( ! blockNames ) {
return EMPTY_ARRAY;
}
const patterns =
select( STORE_NAME ).__experimentalGetAllowedPatterns(
rootClientId
);
let patterns;

if ( rootClientId ) {
patterns =
select( STORE_NAME ).__experimentalGetAllowedPatterns(
rootClientId
);
} else {
const {
getAllPatterns,
__experimentalGetParsedPattern: getParsedPattern,
} = unlock( select( STORE_NAME ) );
patterns = getAllPatterns()
.filter( ( { inserter = true } ) => !! inserter )
.map( ( { name } ) => getParsedPattern( name ) );
}

const normalizedBlockNames = Array.isArray( blockNames )
? blockNames
: [ blockNames ];
Expand All @@ -2444,7 +2457,11 @@ export const getPatternsByBlockTypes = createRegistrySelector( ( select ) =>
return filteredPatterns;
},
( state, blockNames, rootClientId ) =>
getAllowedPatternsDependants( select )( state, rootClientId )
! rootClientId
? unlock( select( STORE_NAME ) ).getAllPatterns()
: select( STORE_NAME ).__experimentalGetAllowedPatterns(
rootClientId
)
)
);

Expand Down
23 changes: 9 additions & 14 deletions packages/editor/src/components/inserter-sidebar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,26 @@ export default function InserterSidebar() {
getInsertionPoint,
isPublishSidebarOpened,
} = unlock( select( editorStore ) );
const {
getBlockRootClientId,
__unstableGetEditorMode,
getSectionRootClientId,
} = unlock( select( blockEditorStore ) );

const { getSectionRootClientId } = unlock( select( blockEditorStore ) );
const { get } = select( preferencesStore );
const { getActiveComplementaryArea } = select( interfaceStore );

const getBlockSectionRootClientId = () => {
if ( __unstableGetEditorMode() === 'zoom-out' ) {
const sectionRootClientId = getSectionRootClientId();
const sectionRootClientId = getSectionRootClientId();

if ( sectionRootClientId ) {
return sectionRootClientId;
}
}
return getBlockRootClientId();
// '' is equiavlent to calling getBlockRootClientId() with no arguments.
return sectionRootClientId ?? '';
};

return {
inserterSidebarToggleRef: getInserterSidebarToggleRef(),
insertionPoint: getInsertionPoint(),
showMostUsedBlocks: get( 'core', 'mostUsedBlocks' ),
blockSectionRootClientId: getBlockSectionRootClientId(),
sidebarIsOpened: !! (
getActiveComplementaryArea( 'core' ) || isPublishSidebarOpened()
),
blockSectionRootClientId: getBlockSectionRootClientId(),
};
}, [] );
const { setIsInserterOpened } = useDispatch( editorStore );
Expand Down Expand Up @@ -89,7 +84,7 @@ export default function InserterSidebar() {
showInserterHelpPanel
shouldFocusBlock={ isMobileViewport }
rootClientId={
blockSectionRootClientId ?? insertionPoint.rootClientId
insertionPoint.rootClientId ?? blockSectionRootClientId
}
__experimentalInsertionIndex={ insertionPoint.insertionIndex }
onSelect={ insertionPoint.onSelect }
Expand Down
70 changes: 65 additions & 5 deletions packages/editor/src/components/start-page-options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
*/
import { Modal } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useState, useMemo } from '@wordpress/element';
import { useMemo, useState } from '@wordpress/element';
import {
store as blockEditorStore,
__experimentalBlockPatternsList as BlockPatternsList,
} from '@wordpress/block-editor';
import { useSelect, useDispatch } from '@wordpress/data';
import { useAsyncList } from '@wordpress/compose';
import { useAsyncList, usePrevious } from '@wordpress/compose';
import { store as coreStore } from '@wordpress/core-data';
import { __unstableSerializeAndClean } from '@wordpress/blocks';
import { store as preferencesStore } from '@wordpress/preferences';
Expand Down Expand Up @@ -118,6 +118,8 @@ function StartPageOptionsModal( { onClose } ) {

export default function StartPageOptions() {
const [ isClosed, setIsClosed ] = useState( false );

// Select for starter page modal.
const shouldEnableModal = useSelect( ( select ) => {
const { isEditedPostDirty, isEditedPostEmpty, getCurrentPostType } =
select( editorStore );
Expand All @@ -136,9 +138,67 @@ export default function StartPageOptions() {
);
}, [] );

if ( ! shouldEnableModal || isClosed ) {
return null;
// Select for starter pattern inserter.
const { shouldEnableStartPage, postType, postId } = useSelect(
( select ) => {
const {
isEditedPostDirty,
isEditedPostEmpty,
getCurrentPostType,
getCurrentPostId,
} = select( editorStore );
const _postType = getCurrentPostType();

return {
shouldEnableStartPage:
! isEditedPostDirty() &&
isEditedPostEmpty() &&
TEMPLATE_POST_TYPE !== _postType,
postType: _postType,
postId: getCurrentPostId(),
};
},
[]
);

const previousPostType = usePrevious( postType );
const previousPostId = usePrevious( postId );

// Reset the isClosed state when navigating to a new page/post.
if (
( previousPostType && previousPostType !== postType ) ||
( previousPostId && previousPostId !== postId )
) {
setIsClosed( false );
}

// A pattern is a start pattern if it includes 'core/post-content' in its
// blockTypes, and it has no postTypes declared and the current post type is
// page or if the current post type is part of the postTypes declared.
const hasStarterPatterns = useSelect(
( select ) =>
!! select( blockEditorStore ).getPatternsByBlockTypes(
'core/post-content'
).length
);

const { setIsInserterOpened } = useDispatch( editorStore );
const { __unstableSetEditorMode } = useDispatch( blockEditorStore );

const showInserterOnNewPage =
shouldEnableStartPage && ! isClosed && hasStarterPatterns;

if ( showInserterOnNewPage ) {
setIsInserterOpened( {
tab: 'patterns',
category: 'core/content',
} );
__unstableSetEditorMode( 'zoom-out' );
}

if ( shouldEnableModal && ! isClosed ) {
return <StartPageOptionsModal onClose={ () => setIsClosed( true ) } />;
}

return <StartPageOptionsModal onClose={ () => setIsClosed( true ) } />;
return null;
}
Loading