diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index 17183d13a87090..8eb43853e519e7 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -20,6 +20,7 @@ import { plus } from '@wordpress/icons'; */ import InserterMenu from './menu'; import QuickInserter from './quick-inserter'; +import ModalInserter from './modal-inserter'; import { store as blockEditorStore } from '../../store'; const defaultRenderToggle = ( { @@ -142,6 +143,7 @@ class Inserter extends Component { // This prop is experimental to give some time for the quick inserter to mature // Feel free to make them stable after a few releases. __experimentalIsQuick: isQuick, + __experimentalIsModal: isModal, prioritizePatterns, } = this.props; @@ -159,6 +161,20 @@ class Inserter extends Component { ); } + if ( isModal ) { + return ( + { + onClose(); + } } + rootClientId={ rootClientId } + clientId={ clientId } + isAppender={ isAppender } + prioritizePatterns={ prioritizePatterns } + /> + ); + } + return ( { @@ -173,6 +189,21 @@ class Inserter extends Component { ); } + renderModal() { + const { rootClientId, clientId, isAppender, prioritizePatterns } = + this.props; + + return ( + null } + rootClientId={ rootClientId } + clientId={ clientId } + isAppender={ isAppender } + prioritizePatterns={ prioritizePatterns } + /> + ); + } + render() { const { position, @@ -180,9 +211,14 @@ class Inserter extends Component { directInsertBlock, insertOnlyAllowedBlock, __experimentalIsQuick: isQuick, + __experimentalIsModal: isModal, onSelectOrClose, } = this.props; + if ( isModal ) { + return this.renderModal(); + } + if ( hasSingleBlockType || directInsertBlock ) { return this.renderToggle( { onToggle: insertOnlyAllowedBlock } ); } diff --git a/packages/block-editor/src/components/inserter/modal-inserter.js b/packages/block-editor/src/components/inserter/modal-inserter.js new file mode 100644 index 00000000000000..b4b43680b1edfc --- /dev/null +++ b/packages/block-editor/src/components/inserter/modal-inserter.js @@ -0,0 +1,118 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { SearchControl } from '@wordpress/components'; +import { useSelect } from '@wordpress/data'; +import { useFocusOnMount } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import InserterSearchResults from './search-results'; +import useInsertionPoint from './hooks/use-insertion-point'; +import usePatternsState from './hooks/use-patterns-state'; +import useBlockTypesState from './hooks/use-block-types-state'; +import { store as blockEditorStore } from '../../store'; + +const SEARCH_THRESHOLD = 6; +const SHOWN_BLOCK_TYPES = 6; +const SHOWN_BLOCK_PATTERNS = 2; +const SHOWN_BLOCK_PATTERNS_WITH_PRIORITIZATION = 4; + +export default function ModalInserter( { + onSelect, + rootClientId, + clientId, + isAppender, + prioritizePatterns, +} ) { + const ref = useFocusOnMount(); + const [ filterValue, setFilterValue ] = useState( '' ); + const [ destinationRootClientId, onInsertBlocks ] = useInsertionPoint( { + onSelect, + rootClientId, + clientId, + isAppender, + } ); + const [ blockTypes ] = useBlockTypesState( + destinationRootClientId, + onInsertBlocks + ); + + const [ patterns ] = usePatternsState( + onInsertBlocks, + destinationRootClientId + ); + + const { setInserterIsOpened } = useSelect( + ( select ) => { + const { getSettings, getBlockIndex, getBlockCount } = + select( blockEditorStore ); + const settings = getSettings(); + const index = getBlockIndex( clientId ); + const blockCount = getBlockCount(); + + return { + setInserterIsOpened: settings.__experimentalSetIsInserterOpened, + insertionIndex: index === -1 ? blockCount : index, + }; + }, + [ clientId ] + ); + + const showPatterns = + patterns.length && ( !! filterValue || prioritizePatterns ); + const showSearch = + ( showPatterns && patterns.length > SEARCH_THRESHOLD ) || + blockTypes.length > SEARCH_THRESHOLD; + + let maxBlockPatterns = 0; + if ( showPatterns ) { + maxBlockPatterns = prioritizePatterns + ? SHOWN_BLOCK_PATTERNS_WITH_PRIORITIZATION + : SHOWN_BLOCK_PATTERNS; + } + + return ( +
+ { showSearch && ( + { + setFilterValue( value ); + } } + label={ __( 'Search for blocks and patterns' ) } + placeholder={ __( 'Search' ) } + /> + ) } + +
+ +
+
+ ); +} diff --git a/packages/edit-post/src/components/header/style.scss b/packages/edit-post/src/components/header/style.scss index 1228688f257097..5e8de475dc866d 100644 --- a/packages/edit-post/src/components/header/style.scss +++ b/packages/edit-post/src/components/header/style.scss @@ -219,7 +219,6 @@ visibility: hidden; } - & > .edit-post-header__toolbar .edit-post-header-toolbar__inserter-toggle, & > .edit-post-header__toolbar .edit-post-header-toolbar__list-view-toggle, & > .edit-post-header__settings > .block-editor-post-preview__dropdown, & > .edit-post-header__settings > .interface-pinned-items { diff --git a/packages/edit-post/src/components/keyboard-shortcuts/index.js b/packages/edit-post/src/components/keyboard-shortcuts/index.js index 19aa1990f8f48a..8c93cfcb0e5e2a 100644 --- a/packages/edit-post/src/components/keyboard-shortcuts/index.js +++ b/packages/edit-post/src/components/keyboard-shortcuts/index.js @@ -24,6 +24,7 @@ function KeyboardShortcuts() { getEditorMode, isEditorSidebarOpened, isListViewOpened, + isInserterOpened, isFeatureActive, } = useSelect( editPostStore ); const isModeToggleDisabled = useSelect( ( select ) => { @@ -94,6 +95,16 @@ function KeyboardShortcuts() { }, } ); + registerShortcut( { + name: 'core/edit-post/toggle-modal-inserter', + category: 'global', + description: __( 'Open modal inserter.' ), + keyCombination: { + modifier: 'access', + character: 'i', + }, + } ); + registerShortcut( { name: 'core/edit-post/toggle-sidebar', category: 'global', @@ -200,6 +211,10 @@ function KeyboardShortcuts() { setIsListViewOpened( ! isListViewOpened() ) ); + useShortcut( 'core/edit-post/toggle-modal-inserter', () => + setIsInserterOpened( ! isInserterOpened() ) + ); + return null; } diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index c1ecb74676f3a5..435d3b0e47133b 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -49,6 +49,7 @@ import WelcomeGuide from '../welcome-guide'; import ActionsPanel from './actions-panel'; import StartPageOptions from '../start-page-options'; import { store as editPostStore } from '../../store'; +import { ModalInserter } from './modal-inserter'; const interfaceLabels = { /* translators: accessibility text for the editor top bar landmark region. */ @@ -174,9 +175,12 @@ function Layout( { styles } ) { : __( 'Block Library' ); const secondarySidebar = () => { - if ( mode === 'visual' && isInserterOpened ) { + if ( mode === 'visual' && ! isDistractionFree && isInserterOpened ) { return ; } + if ( mode === 'visual' && isDistractionFree && isInserterOpened ) { + return ; + } if ( mode === 'visual' && isListViewOpened ) { return ; } diff --git a/packages/edit-post/src/components/layout/modal-inserter.js b/packages/edit-post/src/components/layout/modal-inserter.js new file mode 100644 index 00000000000000..33553c0a1141ae --- /dev/null +++ b/packages/edit-post/src/components/layout/modal-inserter.js @@ -0,0 +1,24 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Modal } from '@wordpress/components'; +import { Inserter } from '@wordpress/block-editor'; +import { useDispatch } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + +export function ModalInserter() { + const { setIsInserterOpened } = useDispatch( editPostStore ); + const closeModal = () => { + setIsInserterOpened( false ); + }; + return ( + + + + ); +}