diff --git a/packages/block-editor/src/components/block-edit/edit.native.js b/packages/block-editor/src/components/block-edit/edit.native.js index 2577ad3e0733e7..80b07374cf11ef 100644 --- a/packages/block-editor/src/components/block-edit/edit.native.js +++ b/packages/block-editor/src/components/block-edit/edit.native.js @@ -1,20 +1,50 @@ +/** + * External dependencies + */ +import { pick } from 'lodash'; + /** * WordPress dependencies */ import { withFilters } from '@wordpress/components'; import { getBlockType } from '@wordpress/blocks'; +import { useContext, useMemo } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import BlockContext from '../block-context'; + +/** + * Default value used for blocks which do not define their own context needs, + * used to guarantee that a block's `context` prop will always be an object. It + * is assigned as a constant since it is always expected to be an empty object, + * and in order to avoid unnecessary React reconciliations of a changing object. + * + * @type {{}} + */ +const DEFAULT_BLOCK_CONTEXT = {}; export const Edit = ( props ) => { const { name } = props; const blockType = getBlockType( name ); + const blockContext = useContext( BlockContext ); + + // Assign context values using the block type's declared context needs. + const context = useMemo( () => { + return blockType && blockType.usesContext + ? pick( blockContext, blockType.usesContext ) + : DEFAULT_BLOCK_CONTEXT; + }, [ blockType, blockContext ] ); + if ( ! blockType ) { return null; } const Component = blockType.edit; - return ; + return ; }; export default withFilters( 'editor.BlockEdit' )( Edit ); diff --git a/packages/block-editor/src/components/block-edit/test/edit.native.js b/packages/block-editor/src/components/block-edit/test/edit.native.js new file mode 100644 index 00000000000000..8bcc3de486f033 --- /dev/null +++ b/packages/block-editor/src/components/block-edit/test/edit.native.js @@ -0,0 +1,64 @@ +/** + * External dependencies + */ +import { shallow, mount } from 'enzyme'; + +/** + * WordPress dependencies + */ +import { + registerBlockType, + unregisterBlockType, + getBlockTypes, +} from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { Edit } from '../edit'; +import { BlockContextProvider } from '../../block-context'; + +describe( 'Edit', () => { + afterEach( () => { + getBlockTypes().forEach( ( block ) => { + unregisterBlockType( block.name ); + } ); + } ); + + it( 'should return null if block type not defined', () => { + const wrapper = shallow( ); + + expect( wrapper.type() ).toBe( null ); + } ); + + it( 'should use edit implementation of block', () => { + const edit = () =>
; + registerBlockType( 'core/test-block', { + category: 'text', + title: 'block title', + edit, + } ); + + const wrapper = shallow( ); + + expect( wrapper.exists( edit ) ).toBe( true ); + } ); + + it( 'should assign context', () => { + const edit = ( { context } ) => context.value; + registerBlockType( 'core/test-block', { + category: 'text', + title: 'block title', + usesContext: [ 'value' ], + edit, + } ); + + const wrapper = mount( + + + + ); + + expect( wrapper.html() ).toBe( 'Ok' ); + } ); +} );