The title is kind of incomplete. Look at the image above, especially at the Media Library button. This button is implemented using the MediaUpload component. This article will help you to add React elements or components around the MediaUpload component which is also used in the core/video
and core/audio
blocks.
This article requires basic knowledge of Higher-Order components, also known as HOCs.
The code below is documented and explains a few concepts to get started.
import { addFilter } from "@wordpress/hooks";
/**
* Adds some useless elements around the MediaUpload component.
* @param {React.ComponentType} Component The MediaUpload component.
* @returns {React.FC} Returns the Wrapped component.
*
* The `addHtmlAround` function is a Higher Order Component
* that accepts a Component as argument and returns a Component
* as well. In our case, the Component passed is the
* MediaUpload component.
*/
function addHtmlAround( Component ) {
/**
* Notice that this function returns a function.
* The `props` are the same props that are passed to
* the MediaUpload component.
*/
return ( props ) => {
return <Component { ...props } />
};
}
addFilter(
'editor.MediaUpload',
'the-wordpress-voyage/do-nothing-button',
addHtmlAround
);
Code language: JavaScript (javascript)
The hook we are using to add elements/components is editor.MediaUpload
.
Understanding the code above
The code is in its most minimal form. It does absolutely nothing. It accepts the MediaUpload
component and returns it as it is. It is as good as not running the code above.
Let’s experiment with it to add some <div />
elements around the <Component />
.
function addHtmlAround( Component ) {
/**
* Notice that this function returns a function.
* The `props` are the same props that are passed to
* the MediaUpload component.
*/
return ( props ) => {
return (
<>
<div>Before</div>
<Component { ...props } />
<div>After</div>
</>
)
};
}
Code language: JavaScript (javascript)
With the code above, if you add an Image, Audio or a Video block, you’ll see the following:
To keep the example simple, we did not add any functionality. But you can add a <Button />
instead which can perform a specific task.
Excluding specific blocks
Suppose if you want to add buttons to only the image block. You can do that by adding the following:
function addHtmlAround( Component ) {
/**
* Notice that this function returns a function.
* The `props` are the same props that are passed to
* the MediaUpload component.
*/
return ( props ) => {
let blockProps;
try {
/**
* The try-catch is important, because the
* `MediaUpload` component can be used outside
* the block context as well. For example, the
* Featured Image button is not a block, and using
* the `useBlockProps()` function will throw an
* exception which we catch here.
*/
blockProps = useBlockProps();
} catch ( e ) {
/**
* Return the original component as it is if
* `useBlockProps()` throws an exception when
* this code runs outside of the Block context.
*/
return <Component { ...props } />;
}
const { 'data-type': blockName } = blockProps;
if ( 'core/image' !== blockName ) {
return <Component { ...props } />;
}
return (
<>
<div>Before</div>
<Component { ...props } />
<div>After</div>
</>
)
};
}
Code language: JavaScript (javascript)
That’s all! Hope you had fun reading, thank you!
Leave a Reply