-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor starter patterns to editor package
Add start page options modal to site editor Move component to block editor Avoid bug where context is not defined until the store is populated Find the content block in the page and use that as the basis for finding and inserting patterns Refactor modal closed state out of base component Update classnames to correct convention Remove double useSelect Remove unnecessary comments Select inserted pattern
- Loading branch information
Showing
8 changed files
with
205 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
packages/block-editor/src/components/starter-patterns-modal/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { Modal } from '@wordpress/components'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { useMemo } from '@wordpress/element'; | ||
import { useSelect } from '@wordpress/data'; | ||
import { useAsyncList } from '@wordpress/compose'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { store as blockEditorStore } from '../../store'; | ||
import { __experimentalBlockPatternsList as BlockPatternsList } from '../'; | ||
|
||
function useStarterPatterns( postType, rootClientId ) { | ||
// 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 = useSelect( | ||
( select ) => | ||
select( blockEditorStore ).getPatternsByBlockTypes( | ||
'core/post-content', | ||
rootClientId | ||
), | ||
[ rootClientId ] | ||
); | ||
|
||
return useMemo( () => { | ||
// 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 ] ); | ||
} | ||
|
||
export default function StarterPatternsModal( { | ||
onChoosePattern, | ||
onRequestClose, | ||
postType, | ||
rootClientId, | ||
} ) { | ||
const starterPatterns = useStarterPatterns( postType, rootClientId ); | ||
const shownStarterPatterns = useAsyncList( starterPatterns ); | ||
|
||
if ( starterPatterns.length === 0 ) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Modal | ||
title={ __( 'Choose a pattern' ) } | ||
isFullScreen | ||
onRequestClose={ onRequestClose } | ||
> | ||
<div className="block-editor-starter-patterns-modal__content"> | ||
<BlockPatternsList | ||
blockPatterns={ starterPatterns } | ||
shownPatterns={ shownStarterPatterns } | ||
onClickPattern={ onChoosePattern } | ||
/> | ||
</div> | ||
</Modal> | ||
); | ||
} |
26 changes: 26 additions & 0 deletions
26
packages/block-editor/src/components/starter-patterns-modal/style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// 2 column masonry layout. | ||
.block-editor-starter-patterns-modal__content .block-editor-block-patterns-list { | ||
column-count: 2; | ||
column-gap: $grid-unit-30; | ||
|
||
@include break-medium() { | ||
column-count: 3; | ||
} | ||
|
||
@include break-wide() { | ||
column-count: 4; | ||
} | ||
|
||
.block-editor-block-patterns-list__list-item { | ||
break-inside: avoid-column; | ||
margin-bottom: $grid-unit-30; | ||
|
||
.block-editor-block-preview__container { | ||
min-height: 100px; | ||
} | ||
|
||
.block-editor-block-preview__content { | ||
width: 100%; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 22 additions & 86 deletions
108
packages/edit-post/src/components/start-page-options/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,44 @@ | ||
/** | ||
* 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 { useSelect, useDispatch } from '@wordpress/data'; | ||
import { useAsyncList } from '@wordpress/compose'; | ||
import { store as editorStore } from '@wordpress/editor'; | ||
import { useState } from '@wordpress/element'; | ||
import { StarterPatternsModal } from '@wordpress/block-editor'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { store as editPostStore } from '../../store'; | ||
|
||
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 } = select( blockEditorStore ); | ||
const { getCurrentPostType } = select( editorStore ); | ||
return { | ||
blockPatternsWithPostContentBlockType: | ||
getPatternsByBlockTypes( 'core/post-content' ), | ||
postType: getCurrentPostType(), | ||
}; | ||
}, | ||
[] | ||
); | ||
|
||
return useMemo( () => { | ||
// 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 shownBlockPatterns = useAsyncList( blockPatterns ); | ||
const { resetEditorBlocks } = useDispatch( editorStore ); | ||
return ( | ||
<BlockPatternsList | ||
blockPatterns={ blockPatterns } | ||
shownPatterns={ shownBlockPatterns } | ||
onClickPattern={ ( _pattern, blocks ) => { | ||
resetEditorBlocks( blocks ); | ||
onChoosePattern(); | ||
} } | ||
/> | ||
); | ||
} | ||
|
||
function StartPageOptionsModal( { onClose } ) { | ||
const startPatterns = useStartPatterns(); | ||
const hasStartPattern = startPatterns.length > 0; | ||
|
||
if ( ! hasStartPattern ) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Modal | ||
className="edit-post-start-page-options__modal" | ||
title={ __( 'Choose a pattern' ) } | ||
isFullScreen | ||
onRequestClose={ onClose } | ||
> | ||
<div className="edit-post-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 { isCleanNewPost } = select( editorStore ); | ||
const { resetEditorBlocks } = useDispatch( editorStore ); | ||
const { shouldEnableModal, postType } = useSelect( ( select ) => { | ||
const { isCleanNewPost, getCurrentPostType } = select( editorStore ); | ||
const { isEditingTemplate, isFeatureActive } = select( editPostStore ); | ||
|
||
return ( | ||
! isEditingTemplate() && | ||
! isFeatureActive( 'welcomeGuide' ) && | ||
isCleanNewPost() | ||
); | ||
return { | ||
shouldEnableModal: | ||
! isEditingTemplate() && | ||
! isFeatureActive( 'welcomeGuide' ) && | ||
isCleanNewPost(), | ||
postType: getCurrentPostType(), | ||
}; | ||
}, [] ); | ||
|
||
if ( ! shouldEnableModal || isClosed ) { | ||
return null; | ||
} | ||
|
||
return <StartPageOptionsModal onClose={ () => setIsClosed( true ) } />; | ||
return ( | ||
<StarterPatternsModal | ||
postType={ postType } | ||
onChoosePattern={ ( pattern, blocks ) => { | ||
resetEditorBlocks( blocks ); | ||
setIsClosed( true ); | ||
} } | ||
onRequestClose={ () => setIsClosed( true ) } | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
packages/edit-site/src/components/start-page-options/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
store as blockEditorStore, | ||
StarterPatternsModal, | ||
} from '@wordpress/block-editor'; | ||
import { useDispatch, useSelect } from '@wordpress/data'; | ||
import { useState } from '@wordpress/element'; | ||
import { store as preferencesStore } from '@wordpress/preferences'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { store as editSiteStore } from '../../store'; | ||
|
||
export default function StartPageOptions() { | ||
const { replaceInnerBlocks } = useDispatch( blockEditorStore ); | ||
const [ isClosed, setIsClosed ] = useState( false ); | ||
const { shouldOpenModal, postType, rootClientId } = useSelect( | ||
( select ) => { | ||
const { hasPageContentFocus, getEditedPostContext } = | ||
select( editSiteStore ); | ||
const context = getEditedPostContext(); | ||
const isEditingPage = | ||
context?.postType === 'page' && | ||
context?.postId && | ||
hasPageContentFocus(); | ||
const isWelcomeGuideOpen = select( preferencesStore ).get( | ||
'core/edit-site', | ||
'welcomeGuide' | ||
); | ||
if ( ! isEditingPage || isWelcomeGuideOpen ) { | ||
return { shouldOpenModal: false }; | ||
} | ||
|
||
const { __experimentalGetGlobalBlocksByName, getBlock } = | ||
select( blockEditorStore ); | ||
const [ contentBlockClientId ] = | ||
__experimentalGetGlobalBlocksByName( 'core/post-content' ); | ||
if ( ! contentBlockClientId ) { | ||
return { shouldOpenModal: false }; | ||
} | ||
|
||
const contentBlock = getBlock( contentBlockClientId ); | ||
if ( contentBlock?.innerBlocks?.length ) { | ||
return { shouldOpenModal: false }; | ||
} | ||
|
||
return { | ||
shouldOpenModal: true, | ||
postType: context.postType, | ||
rootClientId: contentBlockClientId, | ||
}; | ||
}, | ||
[] | ||
); | ||
|
||
if ( isClosed || ! shouldOpenModal ) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<StarterPatternsModal | ||
postType={ postType } | ||
rootClientId={ rootClientId } | ||
onChoosePattern={ ( pattern, blocks ) => { | ||
setIsClosed( true ); | ||
const selectInsertedBlocks = true; | ||
replaceInnerBlocks( | ||
rootClientId, | ||
blocks, | ||
selectInsertedBlocks | ||
); | ||
} } | ||
onRequestClose={ () => setIsClosed( true ) } | ||
/> | ||
); | ||
} |