diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index 50e388f31b3c8..977ecce2ffde7 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -47,6 +47,7 @@ import SettingsSidebar from '../sidebar/settings-sidebar'; import MetaBoxes from '../meta-boxes'; import WelcomeGuide from '../welcome-guide'; import ActionsPanel from './actions-panel'; +import StartPageOptions from '../start-page-options'; import { store as editPostStore } from '../../store'; const interfaceLabels = { @@ -286,6 +287,7 @@ function Layout( { styles } ) { + diff --git a/packages/edit-post/src/components/start-page-options/index.js b/packages/edit-post/src/components/start-page-options/index.js new file mode 100644 index 0000000000000..6f9e0cebe57de --- /dev/null +++ b/packages/edit-post/src/components/start-page-options/index.js @@ -0,0 +1,121 @@ +/** + * WordPress dependencies + */ +import { Modal } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { useState, useEffect } 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'; + +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + +function PatternSelection( { onChoosePattern } ) { + const { blockPatterns } = useSelect( ( select ) => { + const { __experimentalGetPatternsByBlockTypes } = select( + blockEditorStore + ); + return { + blockPatterns: __experimentalGetPatternsByBlockTypes( + 'core/post-content' + ), + }; + }, [] ); + const shownBlockPatterns = useAsyncList( blockPatterns ); + const { resetEditorBlocks } = useDispatch( editorStore ); + useEffect( () => { + if ( blockPatterns.length <= 1 ) { + onChoosePattern(); + } + }, [ blockPatterns.length ] ); + return ( + { + resetEditorBlocks( blocks ); + onChoosePattern(); + } } + /> + ); +} + +const START_PAGE_MODAL_STATES = { + INITIAL: 'INITIAL', + PATTERN: 'PATTERN', + CLOSED: 'CLOSED', +}; + +export default function StartPageOptions() { + const [ modalState, setModalState ] = useState( + START_PAGE_MODAL_STATES.INITIAL + ); + const shouldOpenModel = useSelect( + ( select ) => { + if ( modalState !== START_PAGE_MODAL_STATES.INITIAL ) { + return false; + } + const { __experimentalGetPatternsByBlockTypes } = select( + blockEditorStore + ); + const { + getCurrentPostType, + getEditedPostContent, + isEditedPostSaveable, + } = select( editorStore ); + const { isEditingTemplate, isFeatureActive } = select( + editPostStore + ); + return ( + getCurrentPostType() === 'page' && + ! isEditedPostSaveable() && + '' === getEditedPostContent() && + ! isEditingTemplate() && + ! isFeatureActive( 'welcomeGuide' ) && + __experimentalGetPatternsByBlockTypes( 'core/post-content' ) + .length >= 1 + ); + }, + [ modalState ] + ); + + useEffect( () => { + if ( shouldOpenModel ) { + setModalState( START_PAGE_MODAL_STATES.PATTERN ); + } + }, [ shouldOpenModel ] ); + + if ( + modalState === START_PAGE_MODAL_STATES.INITIAL || + modalState === START_PAGE_MODAL_STATES.CLOSED + ) { + return null; + } + return ( + { + setModalState( START_PAGE_MODAL_STATES.CLOSED ); + } } + > +
+ { modalState === START_PAGE_MODAL_STATES.PATTERN && ( + { + setModalState( START_PAGE_MODAL_STATES.CLOSED ); + } } + /> + ) } +
+
+ ); +} diff --git a/packages/edit-post/src/components/start-page-options/style.scss b/packages/edit-post/src/components/start-page-options/style.scss new file mode 100644 index 0000000000000..3039977c69fb3 --- /dev/null +++ b/packages/edit-post/src/components/start-page-options/style.scss @@ -0,0 +1,42 @@ +.edit-post-start-page-options__modal { + // To keep modal dimensions consistent as subsections are navigated, width + // and height are used instead of max-(width/height). + @include break-small() { + width: calc(100% - #{ $grid-unit-20 * 2 }); + height: calc(100% - #{ $header-height * 2 }); + } + @include break-medium() { + width: $break-medium - $grid-unit-20 * 2; + } + @include break-large() { + height: 70%; + } + + // @todo: Consider this for a minimal modal prop. + .components-modal__header { + border-bottom: none; + } + + .components-modal__content::before { + content: none; + } +} + +// 2 column masonry layout. +.edit-post-start-page-options__modal-content .block-editor-block-patterns-list { + column-count: 2; + column-gap: $grid-unit-30; + + .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%; + } + } +} diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index a8360e0d8be2b..c4ec7dc7100df 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -22,6 +22,7 @@ @import "./components/text-editor/style.scss"; @import "./components/visual-editor/style.scss"; @import "./components/welcome-guide/style.scss"; +@import "./components/start-page-options/style.scss"; /** * Animations