@wordpress/block-editor
Version:
144 lines (138 loc) • 4.07 kB
JavaScript
/**
* External dependencies
*/
import classNames from 'classnames';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useViewportMatch } from '@wordpress/compose';
import {
__experimentalItemGroup as ItemGroup,
__experimentalItem as Item,
__experimentalHStack as HStack,
FlexBlock,
Button,
} from '@wordpress/components';
import { useCallback, useMemo } from '@wordpress/element';
import { Icon, chevronRight } from '@wordpress/icons';
/**
* Internal dependencies
*/
import { MediaCategoryPanel } from './media-panel';
import MediaUploadCheck from '../../media-upload/check';
import MediaUpload from '../../media-upload';
import { useMediaCategories } from './hooks';
import { getBlockAndPreviewFromMedia } from './utils';
import MobileTabNavigation from '../mobile-tab-navigation';
const ALLOWED_MEDIA_TYPES = [ 'image', 'video', 'audio' ];
function MediaTab( {
rootClientId,
selectedCategory,
onSelectCategory,
onInsert,
} ) {
const mediaCategories = useMediaCategories( rootClientId );
const isMobile = useViewportMatch( 'medium', '<' );
const baseCssClass = 'block-editor-inserter__media-tabs';
const onSelectMedia = useCallback(
( media ) => {
if ( ! media?.url ) {
return;
}
const [ block ] = getBlockAndPreviewFromMedia( media, media.type );
onInsert( block );
},
[ onInsert ]
);
const mobileMediaCategories = useMemo(
() =>
mediaCategories.map( ( mediaCategory ) => ( {
...mediaCategory,
label: mediaCategory.labels.name,
} ) ),
[ mediaCategories ]
);
return (
<>
{ ! isMobile && (
<div className={ `${ baseCssClass }-container` }>
<nav aria-label={ __( 'Media categories' ) }>
<ItemGroup role="list" className={ baseCssClass }>
{ mediaCategories.map( ( mediaCategory ) => (
<Item
role="listitem"
key={ mediaCategory.name }
onClick={ () =>
onSelectCategory( mediaCategory )
}
className={ classNames(
`${ baseCssClass }__media-category`,
{
'is-selected':
selectedCategory ===
mediaCategory,
}
) }
aria-label={ mediaCategory.labels.name }
aria-current={
mediaCategory === selectedCategory
? 'true'
: undefined
}
>
<HStack>
<FlexBlock>
{ mediaCategory.labels.name }
</FlexBlock>
<Icon icon={ chevronRight } />
</HStack>
</Item>
) ) }
<div role="listitem">
<MediaUploadCheck>
<MediaUpload
multiple={ false }
onSelect={ onSelectMedia }
allowedTypes={ ALLOWED_MEDIA_TYPES }
render={ ( { open } ) => (
<Button
onClick={ ( event ) => {
// Safari doesn't emit a focus event on button elements when
// clicked and we need to manually focus the button here.
// The reason is that core's Media Library modal explicitly triggers a
// focus event and therefore a `blur` event is triggered on a different
// element, which doesn't contain the `data-unstable-ignore-focus-outside-for-relatedtarget`
// attribute making the Inserter dialog to close.
event.target.focus();
open();
} }
className="block-editor-inserter__media-library-button"
variant="secondary"
data-unstable-ignore-focus-outside-for-relatedtarget=".media-modal"
>
{ __( 'Open Media Library' ) }
</Button>
) }
/>
</MediaUploadCheck>
</div>
</ItemGroup>
</nav>
</div>
) }
{ isMobile && (
<MobileTabNavigation categories={ mobileMediaCategories }>
{ ( category ) => (
<MediaCategoryPanel
onInsert={ onInsert }
rootClientId={ rootClientId }
category={ category }
/>
) }
</MobileTabNavigation>
) }
</>
);
}
export default MediaTab;