@wordpress/block-editor
Version:
148 lines (140 loc) • 3.37 kB
JavaScript
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { useMemo, useRef, memo } from '@wordpress/element';
import {
createBlock,
createBlocksFromInnerBlocksTemplate,
} from '@wordpress/blocks';
import { ENTER } from '@wordpress/keycodes';
/**
* Internal dependencies
*/
import BlockIcon from '../block-icon';
import { InserterListboxItem } from '../inserter-listbox';
import InserterDraggableBlocks from '../inserter-draggable-blocks';
/**
* Return true if platform is MacOS.
*
* @param {Object} _window window object by default; used for DI testing.
*
* @return {boolean} True if MacOS; false otherwise.
*/
function isAppleOS( _window = window ) {
const { platform } = _window.navigator;
return (
platform.indexOf( 'Mac' ) !== -1 ||
[ 'iPad', 'iPhone' ].includes( platform )
);
}
function InserterListItem( {
className,
isFirst,
item,
onSelect,
onHover,
isDraggable,
...props
} ) {
const isDragging = useRef( false );
const itemIconStyle = item.icon
? {
backgroundColor: item.icon.background,
color: item.icon.foreground,
}
: {};
const blocks = useMemo( () => {
return [
createBlock(
item.name,
item.initialAttributes,
createBlocksFromInnerBlocksTemplate( item.innerBlocks )
),
];
}, [ item.name, item.initialAttributes, item.initialAttributes ] );
return (
<InserterDraggableBlocks
isEnabled={ isDraggable && ! item.disabled }
blocks={ blocks }
icon={ item.icon }
>
{ ( { draggable, onDragStart, onDragEnd } ) => (
<div
className="block-editor-block-types-list__list-item"
draggable={ draggable }
onDragStart={ ( event ) => {
isDragging.current = true;
if ( onDragStart ) {
onHover( null );
onDragStart( event );
}
} }
onDragEnd={ ( event ) => {
isDragging.current = false;
if ( onDragEnd ) {
onDragEnd( event );
}
} }
>
<InserterListboxItem
isFirst={ isFirst }
className={ classnames(
'block-editor-block-types-list__item',
className
) }
disabled={ item.isDisabled }
onClick={ ( event ) => {
event.preventDefault();
onSelect(
item,
isAppleOS() ? event.metaKey : event.ctrlKey
);
onHover( null );
} }
onKeyDown={ ( event ) => {
const { keyCode } = event;
if ( keyCode === ENTER ) {
event.preventDefault();
onSelect(
item,
isAppleOS() ? event.metaKey : event.ctrlKey
);
onHover( null );
}
} }
onFocus={ () => {
if ( isDragging.current ) {
return;
}
onHover( item );
} }
onMouseEnter={ () => {
if ( isDragging.current ) {
return;
}
onHover( item );
} }
onMouseLeave={ () => onHover( null ) }
onBlur={ () => onHover( null ) }
{ ...props }
>
<span
className="block-editor-block-types-list__item-icon"
style={ itemIconStyle }
>
<BlockIcon icon={ item.icon } showColors />
</span>
<span className="block-editor-block-types-list__item-title">
{ item.title }
</span>
</InserterListboxItem>
</div>
) }
</InserterDraggableBlocks>
);
}
export default memo( InserterListItem );