Skip to content

Commit

Permalink
Replace Starter Content modal with inserter panel
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Nov 11, 2024
1 parent 27e27a1 commit 5ac2a48
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import { usePatternCategories } from '../block-patterns-tab/use-pattern-categori

function PatternsExplorer( { initialCategory, rootClientId } ) {
const [ searchValue, setSearchValue ] = useState( '' );
const [ selectedCategory, setSelectedCategory ] = useState(
initialCategory?.name
);
const [ selectedCategory, setSelectedCategory ] =
useState( initialCategory );

const patternCategories = usePatternCategories( rootClientId );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ function BlockPatternsTab( {
) }
{ showPatternsExplorer && (
<PatternsExplorerModal
initialCategory={ selectedCategory || categories[ 0 ] }
initialCategory={
selectedCategory || categories[ 0 ]?.name
}
patternCategories={ categories }
onModalClose={ () => setShowPatternsExplorer( false ) }
rootClientId={ rootClientId }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function PatternCategoryPreviews( {
const [ allPatterns, , onClickPattern ] = usePatternsState(
onInsert,
rootClientId,
category?.name
category
);
const [ patternSyncFilter, setPatternSyncFilter ] = useState( 'all' );
const [ patternSourceFilter, setPatternSourceFilter ] = useState( 'all' );
Expand All @@ -76,25 +76,25 @@ export function PatternCategoryPreviews( {
return false;
}

if ( category.name === allPatternsCategory.name ) {
if ( category === allPatternsCategory.name ) {
return true;
}

if (
category.name === myPatternsCategory.name &&
category === myPatternsCategory.name &&
pattern.type === INSERTER_PATTERN_TYPES.user
) {
return true;
}

if (
category.name === starterPatternsCategory.name &&
category === starterPatternsCategory.name &&
pattern.blockTypes?.includes( 'core/post-content' )
) {
return true;
}

if ( category.name === 'uncategorized' ) {
if ( category === 'uncategorized' ) {
// The uncategorized category should show all the patterns without any category...
if ( ! pattern.categories ) {
return true;
Expand All @@ -106,20 +106,24 @@ export function PatternCategoryPreviews( {
);
}

return pattern.categories?.includes( category.name );
return pattern.categories?.includes( category );
} ),
[
allPatterns,
availableCategories,
category.name,
category,
patternSourceFilter,
patternSyncFilter,
]
);

const categoryObject = availableCategories.find(
( { name } ) => name === category
);

const pagingProps = usePatternsPaging(
currentCategoryPatterns,
category,
categoryObject,
scrollContainerRef
);
const { changePage } = pagingProps;
Expand Down Expand Up @@ -156,7 +160,7 @@ export function PatternCategoryPreviews( {
level={ 4 }
as="div"
>
{ category.label }
{ categoryObject.label }
</Heading>
</FlexBlock>
<PatternsFilter
Expand All @@ -165,7 +169,7 @@ export function PatternCategoryPreviews( {
setPatternSyncFilter={ onSetPatternSyncFilter }
setPatternSourceFilter={ onSetPatternSourceFilter }
scrollContainerRef={ scrollContainerRef }
category={ category }
category={ categoryObject }
/>
</HStack>
{ ! currentCategoryPatterns.length && (
Expand Down Expand Up @@ -193,9 +197,9 @@ export function PatternCategoryPreviews( {
blockPatterns={ pagingProps.categoryPatterns }
onClickPattern={ onClickPattern }
onHover={ onHover }
label={ category.label }
label={ categoryObject.label }
orientation="vertical"
category={ category.name }
category={ categoryObject.name }
isDraggable
showTitlesAsTooltip={ showTitlesAsTooltip }
patternFilter={ patternSourceFilter }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,23 @@ function CategoryTabs( {

const previousSelectedCategory = usePrevious( selectedCategory );

const selectedTabId = selectedCategory ? selectedCategory.name : null;
const [ activeTabId, setActiveId ] = useState();
const firstTabId = categories?.[ 0 ]?.name;
useEffect( () => {
// If there is no active tab, make the first tab the active tab, so that
// when focus is moved to the tablist, the first tab will be focused
// despite not being selected
if ( selectedTabId === null && ! activeTabId && firstTabId ) {
if ( selectedCategory === null && ! activeTabId && firstTabId ) {
setActiveId( firstTabId );
}
}, [ selectedTabId, activeTabId, firstTabId, setActiveId ] );
}, [ selectedCategory, activeTabId, firstTabId, setActiveId ] );

return (
<Tabs
selectOnMove={ false }
selectedTabId={ selectedTabId }
selectedTabId={ selectedCategory }
orientation="vertical"
onSelect={ ( categoryId ) => {
// Pass the full category object
onSelectCategory(
categories.find(
( category ) => category.name === categoryId
)
);
} }
onSelect={ onSelectCategory }
activeTabId={ activeTabId }
onActiveTabIdChange={ setActiveId }
>
Expand All @@ -67,7 +59,9 @@ function CategoryTabs( {
tabId={ category.name }
aria-label={ category.label }
aria-current={
category === selectedCategory ? 'true' : undefined
category.name === selectedCategory
? 'true'
: undefined
}
>
{ category.label }
Expand Down
125 changes: 14 additions & 111 deletions packages/editor/src/components/start-page-options/index.js
Original file line number Diff line number Diff line change
@@ -1,121 +1,18 @@
/**
* WordPress dependencies
*/
import { Modal } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useState, useMemo } from '@wordpress/element';
import {
store as blockEditorStore,
__experimentalBlockPatternsList as BlockPatternsList,
} from '@wordpress/block-editor';
import { useEffect } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { __unstableSerializeAndClean } from '@wordpress/blocks';
import { store as preferencesStore } from '@wordpress/preferences';
import { store as interfaceStore } from '@wordpress/interface';

/**
* Internal dependencies
*/
import { store as editorStore } from '../../store';
import { TEMPLATE_POST_TYPE } from '../../store/constants';

export 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.
const { blockPatternsWithPostContentBlockType, postType } = useSelect(
( select ) => {
const { getPatternsByBlockTypes, getBlocksByName } =
select( blockEditorStore );
const { getCurrentPostType, getRenderingMode } =
select( editorStore );
const rootClientId =
getRenderingMode() === 'post-only'
? ''
: getBlocksByName( 'core/post-content' )?.[ 0 ];
return {
blockPatternsWithPostContentBlockType: getPatternsByBlockTypes(
'core/post-content',
rootClientId
),
postType: getCurrentPostType(),
};
},
[]
);

return useMemo( () => {
if ( ! blockPatternsWithPostContentBlockType?.length ) {
return [];
}

/*
* Filter patterns without postTypes declared if the current postType is page
* or patterns that declare the current postType in its post type array.
*/
return blockPatternsWithPostContentBlockType.filter( ( pattern ) => {
return (
( postType === 'page' && ! pattern.postTypes ) ||
( Array.isArray( pattern.postTypes ) &&
pattern.postTypes.includes( postType ) )
);
} );
}, [ postType, blockPatternsWithPostContentBlockType ] );
}

function PatternSelection( { blockPatterns, onChoosePattern } ) {
const { editEntityRecord } = useDispatch( coreStore );
const { postType, postId } = useSelect( ( select ) => {
const { getCurrentPostType, getCurrentPostId } = select( editorStore );

return {
postType: getCurrentPostType(),
postId: getCurrentPostId(),
};
}, [] );
return (
<BlockPatternsList
blockPatterns={ blockPatterns }
onClickPattern={ ( _pattern, blocks ) => {
editEntityRecord( 'postType', postType, postId, {
blocks,
content: ( { blocks: blocksForSerialization = [] } ) =>
__unstableSerializeAndClean( blocksForSerialization ),
} );
onChoosePattern();
} }
/>
);
}

function StartPageOptionsModal( { onClose } ) {
const startPatterns = useStartPatterns();
const hasStartPattern = startPatterns.length > 0;

if ( ! hasStartPattern ) {
return null;
}

return (
<Modal
title={ __( 'Choose a pattern' ) }
isFullScreen
onRequestClose={ onClose }
>
<div className="editor-start-page-options__modal-content">
<PatternSelection
blockPatterns={ startPatterns }
onChoosePattern={ onClose }
/>
</div>
</Modal>
);
}

export default function StartPageOptions() {
const [ isClosed, setIsClosed ] = useState( false );
const shouldEnableModal = useSelect( ( select ) => {
const shouldEnable = useSelect( ( select ) => {
const { isEditedPostDirty, isEditedPostEmpty, getCurrentPostType } =
select( editorStore );
const preferencesModalActive =
Expand All @@ -129,13 +26,19 @@ export default function StartPageOptions() {
! preferencesModalActive &&
! isEditedPostDirty() &&
isEditedPostEmpty() &&
TEMPLATE_POST_TYPE !== getCurrentPostType()
'page' === getCurrentPostType()
);
}, [] );
const { setIsInserterOpened } = useDispatch( editorStore );

useEffect( () => {
if ( shouldEnable ) {
setIsInserterOpened( {
tab: 'patterns',
category: 'core/starter-content',
} );
}
}, [ shouldEnable, setIsInserterOpened ] );

if ( ! shouldEnableModal || isClosed ) {
return null;
}

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

0 comments on commit 5ac2a48

Please sign in to comment.