UNPKG

@wordpress/block-library

Version:
182 lines (161 loc) 4.12 kB
/** * WordPress dependencies */ import { useEntityBlockEditor, store as coreStore } from '@wordpress/core-data'; import { InnerBlocks, useInnerBlocksProps, useSettings, store as blockEditorStore, useBlockEditingMode, } from '@wordpress/block-editor'; import { useSelect } from '@wordpress/data'; import { useMemo } from '@wordpress/element'; import { parse } from '@wordpress/blocks'; function useRenderAppender( hasInnerBlocks ) { const blockEditingMode = useBlockEditingMode(); // Disable appending when the editing mode is 'contentOnly'. This is so that the user can't // append into a template part when editing a page in the site editor. See // DisableNonPageContentBlocks. Ideally instead of (mis)using editing mode there would be a // block editor API for achieving this. if ( blockEditingMode === 'contentOnly' ) { return false; } if ( ! hasInnerBlocks ) { return InnerBlocks.ButtonBlockAppender; } } function useLayout( layout ) { const themeSupportsLayout = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); return getSettings()?.supportsLayout; }, [] ); const [ defaultLayout ] = useSettings( 'layout' ); if ( themeSupportsLayout ) { return layout?.inherit ? defaultLayout || {} : layout; } } function NonEditableTemplatePartPreview( { postId: id, layout, tagName: TagName, blockProps, } ) { useBlockEditingMode( 'disabled' ); const { content, editedBlocks } = useSelect( ( select ) => { if ( ! id ) { return {}; } const { getEditedEntityRecord } = select( coreStore ); const editedRecord = getEditedEntityRecord( 'postType', 'wp_template_part', id, { context: 'view' } ); return { editedBlocks: editedRecord.blocks, content: editedRecord.content, }; }, [ id ] ); const blocks = useMemo( () => { if ( ! id ) { return undefined; } if ( editedBlocks ) { return editedBlocks; } if ( ! content || typeof content !== 'string' ) { return []; } return parse( content ); }, [ id, editedBlocks, content ] ); const innerBlocksProps = useInnerBlocksProps( blockProps, { value: blocks, onInput: () => {}, onChange: () => {}, renderAppender: false, layout: useLayout( layout ), } ); return <TagName { ...innerBlocksProps } />; } function EditableTemplatePartInnerBlocks( { postId: id, hasInnerBlocks, layout, tagName: TagName, blockProps, } ) { const onNavigateToEntityRecord = useSelect( ( select ) => select( blockEditorStore ).getSettings().onNavigateToEntityRecord, [] ); const [ blocks, onInput, onChange ] = useEntityBlockEditor( 'postType', 'wp_template_part', { id } ); const innerBlocksProps = useInnerBlocksProps( blockProps, { value: blocks, onInput, onChange, renderAppender: useRenderAppender( hasInnerBlocks ), layout: useLayout( layout ), } ); const blockEditingMode = useBlockEditingMode(); const customProps = blockEditingMode === 'contentOnly' && onNavigateToEntityRecord ? { onDoubleClick: () => onNavigateToEntityRecord( { postId: id, postType: 'wp_template_part', } ), } : {}; return <TagName { ...innerBlocksProps } { ...customProps } />; } export default function TemplatePartInnerBlocks( { postId: id, hasInnerBlocks, layout, tagName: TagName, blockProps, } ) { const { canViewTemplatePart, canEditTemplatePart } = useSelect( ( select ) => { return { canViewTemplatePart: !! select( coreStore ).canUser( 'read', { kind: 'postType', name: 'wp_template_part', id, } ), canEditTemplatePart: !! select( coreStore ).canUser( 'update', { kind: 'postType', name: 'wp_template_part', id, } ), }; }, [ id ] ); if ( ! canViewTemplatePart ) { return null; } const TemplatePartInnerBlocksComponent = canEditTemplatePart ? EditableTemplatePartInnerBlocks : NonEditableTemplatePartPreview; return ( <TemplatePartInnerBlocksComponent postId={ id } hasInnerBlocks={ hasInnerBlocks } layout={ layout } tagName={ TagName } blockProps={ blockProps } /> ); }