From e0c16f928425c15b0e04aeb7284cf3aae6b2bd36 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 18 Oct 2022 11:51:44 +0300 Subject: [PATCH 01/18] [Inserter]: Add media tab --- .../components/inserter/media-tab/hooks.js | 116 +++++++++++++ .../components/inserter/media-tab/index.js | 3 + .../inserter/media-tab/media-list.js | 111 ++++++++++++ .../inserter/media-tab/media-panel.js | 89 ++++++++++ .../inserter/media-tab/media-tab.js | 163 ++++++++++++++++++ .../src/components/inserter/menu.js | 42 ++++- .../src/components/inserter/style.scss | 149 ++++++++++++++++ .../src/components/inserter/tabs.js | 11 +- packages/core-data/src/fetch/fetch-media.js | 13 ++ packages/core-data/src/fetch/index.js | 1 + .../src/components/block-editor/index.js | 7 +- .../provider/use-block-editor-settings.js | 4 + 12 files changed, 703 insertions(+), 6 deletions(-) create mode 100644 packages/block-editor/src/components/inserter/media-tab/hooks.js create mode 100644 packages/block-editor/src/components/inserter/media-tab/index.js create mode 100644 packages/block-editor/src/components/inserter/media-tab/media-list.js create mode 100644 packages/block-editor/src/components/inserter/media-tab/media-panel.js create mode 100644 packages/block-editor/src/components/inserter/media-tab/media-tab.js create mode 100644 packages/core-data/src/fetch/fetch-media.js diff --git a/packages/block-editor/src/components/inserter/media-tab/hooks.js b/packages/block-editor/src/components/inserter/media-tab/hooks.js new file mode 100644 index 0000000000000..be511b1ac965a --- /dev/null +++ b/packages/block-editor/src/components/inserter/media-tab/hooks.js @@ -0,0 +1,116 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useEffect, useState } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import { useDebounce } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../../store'; + +export function useDebouncedInput() { + const [ input, setInput ] = useState( '' ); + const [ debounced, setter ] = useState( '' ); + const setDebounced = useDebounce( setter, 250 ); + useEffect( () => { + if ( debounced !== input ) { + setDebounced( input ); + } + }, [ debounced, input ] ); + return [ input, setInput, debounced ]; +} + +export function useMediaResults( options = {} ) { + const [ results, setResults ] = useState(); + const settings = useSelect( + ( select ) => select( blockEditorStore ).getSettings(), + [] + ); + useEffect( () => { + ( async () => { + setResults(); + try { + const _media = await settings?.__unstableFetchMedia( options ); + if ( _media ) setResults( _media ); + } catch ( error ) { + // TODO: handle this + throw error; + } + } )(); + }, [ ...Object.values( options ) ] ); + return results; +} + +// TODO: Need to think of the props.. :) +const MEDIA_CATEGORIES = [ + { label: __( 'Images' ), name: 'images', mediaType: 'image' }, + { label: __( 'Videos' ), name: 'videos', mediaType: 'video' }, + { label: __( 'Audio' ), name: 'audio', mediaType: 'audio' }, +]; +export function useMediaCategories( rootClientId ) { + const [ categories, setCategories ] = useState( [] ); + const { canInsertImage, canInsertVideo, canInsertAudio, fetchMedia } = + useSelect( + ( select ) => { + const { canInsertBlockType, getSettings } = + select( blockEditorStore ); + return { + fetchMedia: getSettings().__unstableFetchMedia, + canInsertImage: canInsertBlockType( + 'core/image', + rootClientId + ), + canInsertVideo: canInsertBlockType( + 'core/video', + rootClientId + ), + canInsertAudio: canInsertBlockType( + 'core/audio', + rootClientId + ), + }; + }, + [ rootClientId ] + ); + useEffect( () => { + ( async () => { + // If `__unstableFetchMedia` is not defined in block editor settings, + // do not set any media categories. + if ( ! fetchMedia ) return; + const query = { + context: 'view', + per_page: 1, + _fields: [ 'id' ], + }; + const [ image, video, audio ] = await Promise.all( [ + fetchMedia( { + ...query, + media_type: 'image', + } ), + fetchMedia( { + ...query, + media_type: 'video', + } ), + fetchMedia( { + ...query, + media_type: 'audio', + } ), + ] ); + const showImage = canInsertImage && !! image.length; + const showVideo = canInsertVideo && !! video.length; + const showAudio = canInsertAudio && !! audio.length; + setCategories( + MEDIA_CATEGORIES.filter( + ( { mediaType } ) => + ( mediaType === 'image' && showImage ) || + ( mediaType === 'video' && showVideo ) || + ( mediaType === 'audio' && showAudio ) + ) + ); + } )(); + }, [ canInsertImage, canInsertVideo, canInsertAudio, fetchMedia ] ); + return categories; +} diff --git a/packages/block-editor/src/components/inserter/media-tab/index.js b/packages/block-editor/src/components/inserter/media-tab/index.js new file mode 100644 index 0000000000000..6e4c518ff63b5 --- /dev/null +++ b/packages/block-editor/src/components/inserter/media-tab/index.js @@ -0,0 +1,3 @@ +export { default as MediaTab } from './media-tab'; +export { MediaCategoryDialog } from './media-panel'; +export { useMediaCategories } from './hooks'; diff --git a/packages/block-editor/src/components/inserter/media-tab/media-list.js b/packages/block-editor/src/components/inserter/media-tab/media-list.js new file mode 100644 index 0000000000000..83fbdc98cfa78 --- /dev/null +++ b/packages/block-editor/src/components/inserter/media-tab/media-list.js @@ -0,0 +1,111 @@ +/** + * WordPress dependencies + */ +// import { useInstanceId } from '@wordpress/compose'; +import { + __unstableComposite as Composite, + __unstableUseCompositeState as useCompositeState, + __unstableCompositeItem as CompositeItem, +} from '@wordpress/components'; +import { createBlock } from '@wordpress/blocks'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import InserterDraggableBlocks from '../../inserter-draggable-blocks'; +import BlockPreview from '../../block-preview'; + +function getBlocksPreview( media, mediaType ) { + let attributes; + // TODO: check all the needed attributes(alt, caption, etc..) + if ( mediaType === 'image' ) { + attributes = { + id: media.id, + url: media.source_url, + caption: media.caption?.rendered || undefined, + alt: media.alt_text, + }; + } else if ( mediaType === 'video' || mediaType === 'audio' ) { + attributes = { + id: media.id, + src: media.source_url, + }; + } + return createBlock( `core/${ mediaType }`, attributes ); +} + +function MediaPreview( { media, onClick, composite, mediaType } ) { + const blocks = getBlocksPreview( media, mediaType ); + // TODO: we have to set a max height for previews as the image can be very tall. + // Probably a fixed-max height for all(?). + const title = media.title?.rendered || media.title; + const baseCssClass = 'block-editor-inserter__media-list'; + // const descriptionId = useInstanceId( + // MediaPreview, + // `${ baseCssClass }__item-description` + // ); + return ( + + { ( { draggable, onDragStart, onDragEnd } ) => ( +
+ { + onClick( blocks ); + } } + aria-label={ title } + // aria-describedby={} + > + +
+ { title } +
+ { /* { !! description && ( + + { description } + + ) } */ } +
+
+ ) } +
+ ); +} + +function MediaList( { + results, + mediaType, + onClick, + label = __( 'Media List' ), +} ) { + const composite = useCompositeState(); + return ( + + { results.map( ( media ) => ( + + ) ) } + + ); +} + +export default MediaList; diff --git a/packages/block-editor/src/components/inserter/media-tab/media-panel.js b/packages/block-editor/src/components/inserter/media-tab/media-panel.js new file mode 100644 index 0000000000000..b2622a7f438d0 --- /dev/null +++ b/packages/block-editor/src/components/inserter/media-tab/media-panel.js @@ -0,0 +1,89 @@ +/** + * WordPress dependencies + */ +import { useRef, useEffect } from '@wordpress/element'; +import { Spinner, SearchControl } from '@wordpress/components'; +import { focus } from '@wordpress/dom'; +import { useAsyncList } from '@wordpress/compose'; +import { __, sprintf } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import MediaList from './media-list'; +import { useMediaResults, useDebouncedInput } from './hooks'; +import InserterNoResults from '../no-results'; + +const EMPTY_ARRAY = []; + +export function MediaCategoryDialog( { rootClientId, onInsert, category } ) { + const container = useRef(); + useEffect( () => { + const timeout = setTimeout( () => { + const [ firstTabbable ] = focus.tabbable.find( container.current ); + firstTabbable?.focus(); + } ); + return () => clearTimeout( timeout ); + }, [ category ] ); + return ( +
+ +
+ ); +} + +const INITIAL_MEDIA_ITEMS_PER_PAGE = 10; +export function MediaCategoryPanel( { rootClientId, onInsert, category } ) { + const [ search, setSearch, debouncedSearch ] = useDebouncedInput(); + const results = useMediaResults( { + per_page: !! debouncedSearch ? 20 : INITIAL_MEDIA_ITEMS_PER_PAGE, + media_type: category.mediaType, + search: debouncedSearch, + orderBy: !! debouncedSearch ? 'relevance' : 'date', + } ); + const shownResults = useAsyncList( results || EMPTY_ARRAY, { + step: 3, + } ); + const baseCssClass = 'block-editor-inserter__media-panel'; + return ( +
+ { shownResults !== undefined && ( + + ) } + { ! results && ( +
+ +
+ ) } + { Array.isArray( results ) && ! results.length && ( + + ) } + { !! shownResults?.length && ( + + ) } +
+ ); +} diff --git a/packages/block-editor/src/components/inserter/media-tab/media-tab.js b/packages/block-editor/src/components/inserter/media-tab/media-tab.js new file mode 100644 index 0000000000000..9a3eb7b3615d4 --- /dev/null +++ b/packages/block-editor/src/components/inserter/media-tab/media-tab.js @@ -0,0 +1,163 @@ +/** + * External dependencies + */ +import classNames from 'classnames'; + +/** + * WordPress dependencies + */ +import { __, isRTL } from '@wordpress/i18n'; +import { useViewportMatch } from '@wordpress/compose'; +import { + __experimentalItemGroup as ItemGroup, + __experimentalItem as Item, + __experimentalHStack as HStack, + __experimentalNavigatorProvider as NavigatorProvider, + __experimentalNavigatorScreen as NavigatorScreen, + __experimentalNavigatorButton as NavigatorButton, + __experimentalNavigatorBackButton as NavigatorBackButton, + FlexBlock, + Button, +} from '@wordpress/components'; +import { Icon, chevronRight, chevronLeft } 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'; + +function MediaTab( { + rootClientId, + selectedCategory, + onSelectCategory, + onInsert, +} ) { + const mediaCategories = useMediaCategories( rootClientId ); + const isMobile = useViewportMatch( 'medium', '<' ); + const baseCssClass = 'block-editor-inserter__media-tabs'; + return ( + <> + { ! isMobile && ( +
+ +
+ ) } + { isMobile && ( + + ) } + + ); +} + +function MediaTabNavigation( { onInsert, rootClientId, mediaCategories } ) { + return ( + + + + { mediaCategories.map( ( category ) => ( + + + { category.label } + + + + ) ) } + + + { mediaCategories.map( ( category ) => ( + + + { __( 'Back' ) } + + + + ) ) } + + ); +} + +export default MediaTab; diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js index c6d019c8ff9a7..57d6fd337f025 100644 --- a/packages/block-editor/src/components/inserter/menu.js +++ b/packages/block-editor/src/components/inserter/menu.js @@ -28,6 +28,7 @@ import BlockPatternsTabs, { BlockPatternsCategoryDialog, } from './block-patterns-tab'; import ReusableBlocksTab from './reusable-blocks-tab'; +import { MediaTab, MediaCategoryDialog, useMediaCategories } from './media-tab'; import InserterSearchResults from './search-results'; import useInsertionPoint from './hooks/use-insertion-point'; import InserterTabs from './tabs'; @@ -54,6 +55,8 @@ function InserterMenu( const [ hoveredItem, setHoveredItem ] = useState( null ); const [ selectedPatternCategory, setSelectedPatternCategory ] = useState( null ); + const [ selectedMediaCategory, setSelectedMediaCategory ] = + useState( null ); const [ selectedTab, setSelectedTab ] = useState( null ); const [ destinationRootClientId, onInsertBlocks, onToggleInsertionPoint ] = @@ -68,7 +71,6 @@ function InserterMenu( ( select ) => { const { __experimentalGetAllowedPatterns, getSettings } = select( blockEditorStore ); - return { showPatterns: !! __experimentalGetAllowedPatterns( destinationRootClientId @@ -80,6 +82,9 @@ function InserterMenu( [ destinationRootClientId ] ); + const mediaCategories = useMediaCategories( destinationRootClientId ); + const showMedia = !! mediaCategories.length; + const onInsert = useCallback( ( blocks, meta, shouldForceFocusBlock ) => { onInsertBlocks( blocks, meta, shouldForceFocusBlock ); @@ -170,16 +175,36 @@ function InserterMenu( [ destinationRootClientId, onInsert, onHover ] ); + const mediaTab = useMemo( + () => ( + + ), + [ + destinationRootClientId, + onInsert, + selectedMediaCategory, + setSelectedMediaCategory, + ] + ); + const getCurrentTab = useCallback( ( tab ) => { if ( tab.name === 'blocks' ) { return blocksTab; } else if ( tab.name === 'patterns' ) { return patternsTab; + } else if ( tab.name === 'reusable' ) { + return reusableBlocksTab; + } else if ( tab.name === 'media' ) { + return mediaTab; } - return reusableBlocksTab; }, - [ blocksTab, patternsTab, reusableBlocksTab ] + [ blocksTab, patternsTab, reusableBlocksTab, mediaTab ] ); const searchRef = useRef(); @@ -192,7 +217,8 @@ function InserterMenu( const showPatternPanel = selectedTab === 'patterns' && ! filterValue && selectedPatternCategory; const showAsTabs = ! filterValue && ( showPatterns || hasReusableBlocks ); - + const showMediaPanel = + selectedTab === 'media' && ! filterValue && selectedMediaCategory; return (
@@ -244,6 +271,13 @@ function InserterMenu(
) }
+ { showMediaPanel && ( + + ) } { showInserterHelpPanel && hoveredItem && ( ) } diff --git a/packages/block-editor/src/components/inserter/style.scss b/packages/block-editor/src/components/inserter/style.scss index ad5a2d6642b4a..acd0b601b05e1 100644 --- a/packages/block-editor/src/components/inserter/style.scss +++ b/packages/block-editor/src/components/inserter/style.scss @@ -480,3 +480,152 @@ $block-inserter-tabs-height: 44px; .block-editor-inserter__patterns-category-panel-title { font-size: calc(1.25 * 13px); } + +.block-editor-inserter__media-tabs-container { + height: 100%; + + nav { + height: 100%; + } + + .block-editor-inserter__media-library-button { + padding: $grid-unit-20; + justify-content: center; + margin-top: $grid-unit-20; + width: 100%; + } +} + +.block-editor-inserter__media-tabs { + display: flex; + flex-direction: column; + padding: $grid-unit-20; + overflow-y: auto; + height: 100%; + + &__fill-space { + flex-grow: 1; + } + + &__media-category { + &.is-selected { + color: var(--wp-admin-theme-color); + position: relative; + + .components-flex-item { + filter: brightness(0.95); + } + + svg { + fill: var(--wp-admin-theme-color); + } + + &::after { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + border-radius: $radius-block-ui; + opacity: 0.04; + background: var(--wp-admin-theme-color); + } + } + } +} + +.block-editor-inserter__media-panel { + background: $gray-100; + border-left: $border-width solid $gray-200; + border-right: $border-width solid $gray-200; + position: absolute; + padding: $grid-unit-40 $grid-unit-30; + top: 0; + left: 0; + height: 100%; + width: 100%; + overflow-y: auto; + scrollbar-gutter: stable both-edges; + + @include break-medium { + left: 100%; + display: block; + width: 300px; + } + + .block-editor-block-preview__container { + box-shadow: 0 15px 25px rgb(0 0 0 / 7%); + &:hover { + box-shadow: 0 0 0 2px $gray-900, 0 15px 25px rgb(0 0 0 / 7%); + } + } + + &-title { + font-size: calc(1.25 * 13px); + } + + &-spinner { + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } + + &-search { + &.components-search-control { + input[type="search"].components-search-control__input { + background: $white; + } + } + } +} + +.block-editor-inserter__media-list { + margin-top: $grid-unit-20; + &__list-item { + cursor: pointer; + margin-bottom: $grid-unit-30; + + &.is-placeholder { + min-height: 100px; + } + + &[draggable="true"] .block-editor-block-preview__container { + cursor: grab; + } + } + + &__item { + height: 100%; + + .block-editor-block-preview__container { + display: flex; + align-items: center; + overflow: hidden; + border-radius: 4px; + } + + &-title { + padding-top: $grid-unit-10; + font-size: 12px; + text-align: center; + } + + &:hover &-title, + &:focus &-title { + color: var(--wp-admin-theme-color); + } + + &:hover .block-editor-block-preview__container { + box-shadow: 0 0 0 2px var(--wp-admin-theme-color); + } + + &:focus .block-editor-block-preview__container { + box-shadow: inset 0 0 0 1px $white, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + + // Windows High Contrast mode will show this outline, but not the box-shadow. + outline: 2px solid transparent; + } + } +} diff --git a/packages/block-editor/src/components/inserter/tabs.js b/packages/block-editor/src/components/inserter/tabs.js index 24bfade8b2f4b..da38a7bd75d6c 100644 --- a/packages/block-editor/src/components/inserter/tabs.js +++ b/packages/block-editor/src/components/inserter/tabs.js @@ -22,11 +22,17 @@ const reusableBlocksTab = { title: __( 'Reusable' ), icon: reusableBlockIcon, }; +const mediaTab = { + name: 'media', + /* translators: Media tab title in the block inserter. */ + title: __( 'Media' ), +}; function InserterTabs( { children, showPatterns = false, showReusableBlocks = false, + showMedia = false, onSelect, prioritizePatterns, } ) { @@ -42,7 +48,9 @@ function InserterTabs( { if ( showReusableBlocks ) { tempTabs.push( reusableBlocksTab ); } - + if ( showMedia ) { + tempTabs.push( mediaTab ); + } return tempTabs; }, [ prioritizePatterns, @@ -50,6 +58,7 @@ function InserterTabs( { showPatterns, patternsTab, showReusableBlocks, + showMedia, reusableBlocksTab, ] ); diff --git a/packages/core-data/src/fetch/fetch-media.js b/packages/core-data/src/fetch/fetch-media.js new file mode 100644 index 0000000000000..c7a3a429a8627 --- /dev/null +++ b/packages/core-data/src/fetch/fetch-media.js @@ -0,0 +1,13 @@ +/** + * WordPress dependencies + */ +import { resolveSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { STORE_NAME as coreStore } from '../name'; + +export default async function fetchMedia( settings = {} ) { + return resolveSelect( coreStore ).getMediaItems( settings ); +} diff --git a/packages/core-data/src/fetch/index.js b/packages/core-data/src/fetch/index.js index 8d4d28e3b0db8..2f765825f3e70 100644 --- a/packages/core-data/src/fetch/index.js +++ b/packages/core-data/src/fetch/index.js @@ -1,2 +1,3 @@ export { default as __experimentalFetchLinkSuggestions } from './__experimental-fetch-link-suggestions'; export { default as __experimentalFetchUrlData } from './__experimental-fetch-url-data'; +export { default as __experimentalFetchMedia } from './fetch-media'; diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js index 0f42214b45442..e415d83158e4a 100644 --- a/packages/edit-site/src/components/block-editor/index.js +++ b/packages/edit-site/src/components/block-editor/index.js @@ -8,7 +8,11 @@ import classnames from 'classnames'; */ import { useSelect, useDispatch } from '@wordpress/data'; import { useCallback, useMemo, useRef, Fragment } from '@wordpress/element'; -import { useEntityBlockEditor, store as coreStore } from '@wordpress/core-data'; +import { + useEntityBlockEditor, + __experimentalFetchMedia as fetchMedia, + store as coreStore, +} from '@wordpress/core-data'; import { BlockList, BlockEditorProvider, @@ -131,6 +135,7 @@ export default function BlockEditor( { setIsInserterOpen } ) { return { ...restStoredSettings, + __unstableFetchMedia: ( _settings ) => fetchMedia( _settings ), __experimentalBlockPatterns: blockPatterns, __experimentalBlockPatternCategories: blockPatternCategories, }; diff --git a/packages/editor/src/components/provider/use-block-editor-settings.js b/packages/editor/src/components/provider/use-block-editor-settings.js index 51d16ef1b6a7d..8fc20e3aa6f22 100644 --- a/packages/editor/src/components/provider/use-block-editor-settings.js +++ b/packages/editor/src/components/provider/use-block-editor-settings.js @@ -12,6 +12,7 @@ import { store as coreStore, __experimentalFetchLinkSuggestions as fetchLinkSuggestions, __experimentalFetchUrlData as fetchUrlData, + __experimentalFetchMedia as fetchMedia, } from '@wordpress/core-data'; import { __ } from '@wordpress/i18n'; @@ -183,6 +184,9 @@ function useBlockEditorSettings( settings, hasTemplate ) { __experimentalBlockPatternCategories: blockPatternCategories, __experimentalFetchLinkSuggestions: ( search, searchOptions ) => fetchLinkSuggestions( search, searchOptions, settings ), + // TODO: We should find a proper way to consolidate similar cases + // like reusable blocks, fetch entities, etc. + __unstableFetchMedia: ( _settings ) => fetchMedia( _settings ), __experimentalFetchRichUrlData: fetchUrlData, __experimentalCanUserUseUnfilteredHTML: canUseUnfilteredHTML, __experimentalUndo: undo, From 2a73f2893b7580aaf892845b7026f2a2c7ceb567 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 18 Oct 2022 12:34:53 +0300 Subject: [PATCH 02/18] fix mobile styles --- .../inserter/media-tab/media-panel.js | 4 +-- .../src/components/inserter/style.scss | 32 +++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/media-panel.js b/packages/block-editor/src/components/inserter/media-tab/media-panel.js index b2622a7f438d0..0874dea4a4ce2 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-panel.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-panel.js @@ -14,6 +14,7 @@ import MediaList from './media-list'; import { useMediaResults, useDebouncedInput } from './hooks'; import InserterNoResults from '../no-results'; +const INITIAL_MEDIA_ITEMS_PER_PAGE = 10; const EMPTY_ARRAY = []; export function MediaCategoryDialog( { rootClientId, onInsert, category } ) { @@ -26,7 +27,7 @@ export function MediaCategoryDialog( { rootClientId, onInsert, category } ) { return () => clearTimeout( timeout ); }, [ category ] ); return ( -
+
Date: Mon, 24 Oct 2022 12:21:52 +0300 Subject: [PATCH 03/18] fix media library modal --- .../inserter/media-tab/media-list.js | 23 ++---------------- .../inserter/media-tab/media-tab.js | 15 ++++++++++-- .../components/inserter/media-tab/utils.js | 24 +++++++++++++++++++ .../src/hooks/use-focus-outside/index.ts | 10 ++++++++ 4 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 packages/block-editor/src/components/inserter/media-tab/utils.js diff --git a/packages/block-editor/src/components/inserter/media-tab/media-list.js b/packages/block-editor/src/components/inserter/media-tab/media-list.js index 83fbdc98cfa78..42e5c8c994c57 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-list.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-list.js @@ -7,7 +7,6 @@ import { __unstableUseCompositeState as useCompositeState, __unstableCompositeItem as CompositeItem, } from '@wordpress/components'; -import { createBlock } from '@wordpress/blocks'; import { __ } from '@wordpress/i18n'; /** @@ -15,28 +14,10 @@ import { __ } from '@wordpress/i18n'; */ import InserterDraggableBlocks from '../../inserter-draggable-blocks'; import BlockPreview from '../../block-preview'; - -function getBlocksPreview( media, mediaType ) { - let attributes; - // TODO: check all the needed attributes(alt, caption, etc..) - if ( mediaType === 'image' ) { - attributes = { - id: media.id, - url: media.source_url, - caption: media.caption?.rendered || undefined, - alt: media.alt_text, - }; - } else if ( mediaType === 'video' || mediaType === 'audio' ) { - attributes = { - id: media.id, - src: media.source_url, - }; - } - return createBlock( `core/${ mediaType }`, attributes ); -} +import { getBlocksFromMedia } from './utils'; function MediaPreview( { media, onClick, composite, mediaType } ) { - const blocks = getBlocksPreview( media, mediaType ); + const blocks = getBlocksFromMedia( media, mediaType ); // TODO: we have to set a max height for previews as the image can be very tall. // Probably a fixed-max height for all(?). const title = media.title?.rendered || media.title; diff --git a/packages/block-editor/src/components/inserter/media-tab/media-tab.js b/packages/block-editor/src/components/inserter/media-tab/media-tab.js index 9a3eb7b3615d4..7f5686ccc2697 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-tab.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-tab.js @@ -19,6 +19,7 @@ import { FlexBlock, Button, } from '@wordpress/components'; +import { useCallback } from '@wordpress/element'; import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; /** @@ -28,6 +29,7 @@ import { MediaCategoryPanel } from './media-panel'; import MediaUploadCheck from '../../media-upload/check'; import MediaUpload from '../../media-upload'; import { useMediaCategories } from './hooks'; +import { getBlocksFromMedia } from './utils'; function MediaTab( { rootClientId, @@ -38,6 +40,15 @@ function MediaTab( { const mediaCategories = useMediaCategories( rootClientId ); const isMobile = useViewportMatch( 'medium', '<' ); const baseCssClass = 'block-editor-inserter__media-tabs'; + const onSelectMedia = useCallback( + ( media ) => { + if ( ! media?.url ) { + return; + } + onInsert( getBlocksFromMedia( media, media.type ) ); + }, + [ onInsert ] + ); return ( <> { ! isMobile && ( @@ -83,13 +94,13 @@ function MediaTab( { selectMedia( media, onClose ) } - // allowedTypes={ [ 'image' ] } + onSelect={ onSelectMedia } render={ ( { open } ) => ( diff --git a/packages/block-editor/src/components/inserter/media-tab/utils.js b/packages/block-editor/src/components/inserter/media-tab/utils.js new file mode 100644 index 0000000000000..17472f91f441a --- /dev/null +++ b/packages/block-editor/src/components/inserter/media-tab/utils.js @@ -0,0 +1,24 @@ +/** + * WordPress dependencies + */ +import { createBlock } from '@wordpress/blocks'; + +export function getBlocksFromMedia( media, mediaType ) { + let attributes; + // TODO: check all the needed attributes(alt, caption, poster, etc..) + if ( mediaType === 'image' ) { + attributes = { + id: media.id, + // TODO: check this better(difference between media REST API and `media` object from Media Library). + url: media.source_url || media.url, + caption: media.caption?.rendered || undefined, + alt: media.alt_text, + }; + } else if ( mediaType === 'video' || mediaType === 'audio' ) { + attributes = { + id: media.id, + src: media.source_url || media.url, + }; + } + return createBlock( `core/${ mediaType }`, attributes ); +} diff --git a/packages/compose/src/hooks/use-focus-outside/index.ts b/packages/compose/src/hooks/use-focus-outside/index.ts index cbf1d45d8c9e4..8e6a9af749d77 100644 --- a/packages/compose/src/hooks/use-focus-outside/index.ts +++ b/packages/compose/src/hooks/use-focus-outside/index.ts @@ -151,6 +151,16 @@ export default function useFocusOutside( return; } + // The usage of this attribute should be avoided. The only use case + // would be when we load modals that are not React components and + // therefore don't exist in the React tree. An example is opening + // the Media Library modal from another dialog. + if ( + event.target.hasAttribute( 'data-unstable-ignore-focus-outside' ) + ) { + return; + } + blurCheckTimeoutId.current = setTimeout( () => { // If document is not focused then focus should remain // inside the wrapped component and therefore we cancel From 9fb18769e7853053669e7be12326c1c420dd3443 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 22 Nov 2022 09:07:54 +0200 Subject: [PATCH 04/18] change media tab order --- packages/block-editor/src/components/inserter/tabs.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/inserter/tabs.js b/packages/block-editor/src/components/inserter/tabs.js index da38a7bd75d6c..8a80e96cb78cc 100644 --- a/packages/block-editor/src/components/inserter/tabs.js +++ b/packages/block-editor/src/components/inserter/tabs.js @@ -45,12 +45,12 @@ function InserterTabs( { if ( ! prioritizePatterns && showPatterns ) { tempTabs.push( patternsTab ); } - if ( showReusableBlocks ) { - tempTabs.push( reusableBlocksTab ); - } if ( showMedia ) { tempTabs.push( mediaTab ); } + if ( showReusableBlocks ) { + tempTabs.push( reusableBlocksTab ); + } return tempTabs; }, [ prioritizePatterns, From 58a3b48f3bcf2f99b2493e0a7c717a9f6140cd47 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 22 Nov 2022 10:59:27 +0200 Subject: [PATCH 05/18] add tooltip, style tweaks and cleanup --- .../components/inserter/media-tab/hooks.js | 29 +++--------- .../inserter/media-tab/media-list.js | 45 ++++++++----------- .../inserter/media-tab/media-panel.js | 8 ++-- .../components/inserter/media-tab/utils.js | 28 ++++++------ .../src/components/inserter/style.scss | 2 +- 5 files changed, 44 insertions(+), 68 deletions(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/hooks.js b/packages/block-editor/src/components/inserter/media-tab/hooks.js index be511b1ac965a..bec856573058e 100644 --- a/packages/block-editor/src/components/inserter/media-tab/hooks.js +++ b/packages/block-editor/src/components/inserter/media-tab/hooks.js @@ -32,19 +32,13 @@ export function useMediaResults( options = {} ) { useEffect( () => { ( async () => { setResults(); - try { - const _media = await settings?.__unstableFetchMedia( options ); - if ( _media ) setResults( _media ); - } catch ( error ) { - // TODO: handle this - throw error; - } + const _media = await settings?.__unstableFetchMedia( options ); + if ( _media ) setResults( _media ); } )(); }, [ ...Object.values( options ) ] ); return results; } -// TODO: Need to think of the props.. :) const MEDIA_CATEGORIES = [ { label: __( 'Images' ), name: 'images', mediaType: 'image' }, { label: __( 'Videos' ), name: 'videos', mediaType: 'video' }, @@ -77,8 +71,8 @@ export function useMediaCategories( rootClientId ) { ); useEffect( () => { ( async () => { - // If `__unstableFetchMedia` is not defined in block editor settings, - // do not set any media categories. + // If `__unstableFetchMedia` is not defined in block + // editor settings, do not set any media categories. if ( ! fetchMedia ) return; const query = { context: 'view', @@ -86,18 +80,9 @@ export function useMediaCategories( rootClientId ) { _fields: [ 'id' ], }; const [ image, video, audio ] = await Promise.all( [ - fetchMedia( { - ...query, - media_type: 'image', - } ), - fetchMedia( { - ...query, - media_type: 'video', - } ), - fetchMedia( { - ...query, - media_type: 'audio', - } ), + fetchMedia( { ...query, media_type: 'image' } ), + fetchMedia( { ...query, media_type: 'video' } ), + fetchMedia( { ...query, media_type: 'audio' } ), ] ); const showImage = canInsertImage && !! image.length; const showVideo = canInsertVideo && !! video.length; diff --git a/packages/block-editor/src/components/inserter/media-tab/media-list.js b/packages/block-editor/src/components/inserter/media-tab/media-list.js index 42e5c8c994c57..2189c6be09d60 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-list.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-list.js @@ -6,6 +6,7 @@ import { __unstableComposite as Composite, __unstableUseCompositeState as useCompositeState, __unstableCompositeItem as CompositeItem, + Tooltip, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; @@ -18,14 +19,8 @@ import { getBlocksFromMedia } from './utils'; function MediaPreview( { media, onClick, composite, mediaType } ) { const blocks = getBlocksFromMedia( media, mediaType ); - // TODO: we have to set a max height for previews as the image can be very tall. - // Probably a fixed-max height for all(?). const title = media.title?.rendered || media.title; const baseCssClass = 'block-editor-inserter__media-list'; - // const descriptionId = useInstanceId( - // MediaPreview, - // `${ baseCssClass }__item-description` - // ); return ( { ( { draggable, onDragStart, onDragEnd } ) => ( @@ -35,27 +30,23 @@ function MediaPreview( { media, onClick, composite, mediaType } ) { onDragStart={ onDragStart } onDragEnd={ onDragEnd } > - { - onClick( blocks ); - } } - aria-label={ title } - // aria-describedby={} - > - -
- { title } -
- { /* { !! description && ( - - { description } - - ) } */ } -
+ + { + onClick( blocks ); + } } + aria-label={ title } + > + + +
) } diff --git a/packages/block-editor/src/components/inserter/media-tab/media-panel.js b/packages/block-editor/src/components/inserter/media-tab/media-panel.js index 0874dea4a4ce2..345279bd2dc73 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-panel.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-panel.js @@ -57,14 +57,14 @@ export function MediaCategoryPanel( { rootClientId, onInsert, category } ) { onChange={ setSearch } value={ search } label={ sprintf( - /* translators: %s: Name of the media category(ex. 'Images, Videos'). */ + /* translators: %s: Name of the media category(ex. 'images, videos'). */ __( 'Search %s' ), - category.label + category.label.toLocaleLowerCase() ) } placeholder={ sprintf( - /* translators: %s: Name of the media category(ex. 'Images, Videos'). */ + /* translators: %s: Name of the media category(ex. 'images, videos'). */ __( 'Search %s' ), - category.label + category.label.toLocaleLowerCase() ) } /> ) } diff --git a/packages/block-editor/src/components/inserter/media-tab/utils.js b/packages/block-editor/src/components/inserter/media-tab/utils.js index 17472f91f441a..0911fcd0be77e 100644 --- a/packages/block-editor/src/components/inserter/media-tab/utils.js +++ b/packages/block-editor/src/components/inserter/media-tab/utils.js @@ -4,21 +4,21 @@ import { createBlock } from '@wordpress/blocks'; export function getBlocksFromMedia( media, mediaType ) { - let attributes; - // TODO: check all the needed attributes(alt, caption, poster, etc..) + // Add the common attributes between the different media types. + const attributes = { + id: media.id, + }; + // Some props are named differently between the Media REST API and Media Library API. + // For example `source_url` is used in the former and `url` is used in the latter.. + const caption = media.caption?.rendered || media.caption; + if ( caption && typeof caption === 'string' ) { + attributes.caption = caption; + } if ( mediaType === 'image' ) { - attributes = { - id: media.id, - // TODO: check this better(difference between media REST API and `media` object from Media Library). - url: media.source_url || media.url, - caption: media.caption?.rendered || undefined, - alt: media.alt_text, - }; - } else if ( mediaType === 'video' || mediaType === 'audio' ) { - attributes = { - id: media.id, - src: media.source_url || media.url, - }; + attributes.url = media.source_url || media.url; + attributes.alt = media.alt_text || media.alt || undefined; + } else if ( [ 'video', 'audio' ].includes( mediaType ) ) { + attributes.src = media.source_url || media.url; } return createBlock( `core/${ mediaType }`, attributes ); } diff --git a/packages/block-editor/src/components/inserter/style.scss b/packages/block-editor/src/components/inserter/style.scss index b6fdf9dfa60c4..43fd4fb51b21a 100644 --- a/packages/block-editor/src/components/inserter/style.scss +++ b/packages/block-editor/src/components/inserter/style.scss @@ -540,7 +540,7 @@ $block-inserter-tabs-height: 44px; border-left: $border-width solid $gray-200; border-right: $border-width solid $gray-200; position: absolute; - padding: $grid-unit-40 $grid-unit-30; + padding: $grid-unit-20 $grid-unit-30; top: 0; left: 0; height: 100%; From ce06598eeafde4cf1f71df5c31051440f1389e17 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 22 Nov 2022 11:14:50 +0200 Subject: [PATCH 06/18] memo preview blocks --- .../src/components/inserter/media-tab/media-list.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/media-list.js b/packages/block-editor/src/components/inserter/media-tab/media-list.js index 2189c6be09d60..d332fa97e3cdc 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-list.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-list.js @@ -9,6 +9,7 @@ import { Tooltip, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { useMemo } from '@wordpress/element'; /** * Internal dependencies @@ -18,7 +19,10 @@ import BlockPreview from '../../block-preview'; import { getBlocksFromMedia } from './utils'; function MediaPreview( { media, onClick, composite, mediaType } ) { - const blocks = getBlocksFromMedia( media, mediaType ); + const blocks = useMemo( + () => getBlocksFromMedia( media, mediaType ), + [ media, mediaType ] + ); const title = media.title?.rendered || media.title; const baseCssClass = 'block-editor-inserter__media-list'; return ( From b2d5eaf7f185151cc8558f80cb2263bc5b35c6d4 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 22 Nov 2022 11:39:58 +0200 Subject: [PATCH 07/18] clone media block before insertion --- .../components/inserter/media-tab/media-list.js | 15 +++++++++++---- .../components/inserter/media-tab/media-tab.js | 4 ++-- .../src/components/inserter/media-tab/utils.js | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/media-list.js b/packages/block-editor/src/components/inserter/media-tab/media-list.js index d332fa97e3cdc..a8b224788b47c 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-list.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-list.js @@ -9,18 +9,19 @@ import { Tooltip, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useMemo } from '@wordpress/element'; +import { useMemo, useCallback } from '@wordpress/element'; +import { cloneBlock } from '@wordpress/blocks'; /** * Internal dependencies */ import InserterDraggableBlocks from '../../inserter-draggable-blocks'; import BlockPreview from '../../block-preview'; -import { getBlocksFromMedia } from './utils'; +import { getBlockFromMedia } from './utils'; function MediaPreview( { media, onClick, composite, mediaType } ) { const blocks = useMemo( - () => getBlocksFromMedia( media, mediaType ), + () => getBlockFromMedia( media, mediaType ), [ media, mediaType ] ); const title = media.title?.rendered || media.title; @@ -64,6 +65,12 @@ function MediaList( { label = __( 'Media List' ), } ) { const composite = useCompositeState(); + const onPreviewClick = useCallback( + ( block ) => { + onClick( cloneBlock( block ) ); + }, + [ onClick ] + ); return ( ) ) } diff --git a/packages/block-editor/src/components/inserter/media-tab/media-tab.js b/packages/block-editor/src/components/inserter/media-tab/media-tab.js index 7f5686ccc2697..f890e207b7d8c 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-tab.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-tab.js @@ -29,7 +29,7 @@ import { MediaCategoryPanel } from './media-panel'; import MediaUploadCheck from '../../media-upload/check'; import MediaUpload from '../../media-upload'; import { useMediaCategories } from './hooks'; -import { getBlocksFromMedia } from './utils'; +import { getBlockFromMedia } from './utils'; function MediaTab( { rootClientId, @@ -45,7 +45,7 @@ function MediaTab( { if ( ! media?.url ) { return; } - onInsert( getBlocksFromMedia( media, media.type ) ); + onInsert( getBlockFromMedia( media, media.type ) ); }, [ onInsert ] ); diff --git a/packages/block-editor/src/components/inserter/media-tab/utils.js b/packages/block-editor/src/components/inserter/media-tab/utils.js index 0911fcd0be77e..ffec468b025d7 100644 --- a/packages/block-editor/src/components/inserter/media-tab/utils.js +++ b/packages/block-editor/src/components/inserter/media-tab/utils.js @@ -3,7 +3,7 @@ */ import { createBlock } from '@wordpress/blocks'; -export function getBlocksFromMedia( media, mediaType ) { +export function getBlockFromMedia( media, mediaType ) { // Add the common attributes between the different media types. const attributes = { id: media.id, From ed9e239a76f3972bea43f2d23176004ca40f8dea Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 22 Nov 2022 11:52:48 +0200 Subject: [PATCH 08/18] use only css for `open media library` positioning --- .../src/components/inserter/media-tab/media-tab.js | 5 ----- packages/block-editor/src/components/inserter/style.scss | 5 +++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/media-tab.js b/packages/block-editor/src/components/inserter/media-tab/media-tab.js index f890e207b7d8c..855448882bdc9 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-tab.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-tab.js @@ -85,11 +85,6 @@ function MediaTab( { ) ) } - -
Date: Tue, 22 Nov 2022 12:41:20 +0200 Subject: [PATCH 09/18] use raw caption --- .../block-editor/src/components/inserter/media-tab/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/utils.js b/packages/block-editor/src/components/inserter/media-tab/utils.js index ffec468b025d7..77c0d78790c64 100644 --- a/packages/block-editor/src/components/inserter/media-tab/utils.js +++ b/packages/block-editor/src/components/inserter/media-tab/utils.js @@ -9,8 +9,8 @@ export function getBlockFromMedia( media, mediaType ) { id: media.id, }; // Some props are named differently between the Media REST API and Media Library API. - // For example `source_url` is used in the former and `url` is used in the latter.. - const caption = media.caption?.rendered || media.caption; + // For example `source_url` is used in the former and `url` is used in the latter. + const caption = media.caption?.raw || media.caption; if ( caption && typeof caption === 'string' ) { attributes.caption = caption; } From 805f96641d47885f60b60eee8436becf0f647170 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 22 Nov 2022 13:16:45 +0200 Subject: [PATCH 10/18] inject styles to the block preview iframe content --- .../src/components/block-preview/auto.js | 15 +++++++++++---- .../src/components/block-preview/index.js | 2 ++ .../components/inserter/media-tab/media-list.js | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/block-preview/auto.js b/packages/block-editor/src/components/block-preview/auto.js index ddf4ee0ec75ab..3dad2954688d5 100644 --- a/packages/block-editor/src/components/block-preview/auto.js +++ b/packages/block-editor/src/components/block-preview/auto.js @@ -25,6 +25,7 @@ function ScaledBlockPreview( { containerWidth, __experimentalPadding, __experimentalMinHeight, + __unstableIframeContentStyles, } ) { const [ contentResizeListener, { height: contentHeight } ] = useResizeObserver(); @@ -39,8 +40,12 @@ function ScaledBlockPreview( { // Avoid scrollbars for pattern previews. const editorStyles = useMemo( () => { + if ( ! styles && ! __unstableIframeContentStyles ) { + return; + } + let _editorStyles = []; if ( styles ) { - return [ + _editorStyles = [ ...styles, { css: 'body{height:auto;overflow:hidden;}', @@ -48,9 +53,11 @@ function ScaledBlockPreview( { }, ]; } - - return styles; - }, [ styles ] ); + if ( __unstableIframeContentStyles ) { + _editorStyles.push( { css: __unstableIframeContentStyles } ); + } + return _editorStyles; + }, [ styles, __unstableIframeContentStyles ] ); const svgFilters = useMemo( () => { return [ ...( duotone?.default ?? [] ), ...( duotone?.theme ?? [] ) ]; diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js index 535a67438cad8..cd64e0de395fd 100644 --- a/packages/block-editor/src/components/block-preview/index.js +++ b/packages/block-editor/src/components/block-preview/index.js @@ -23,6 +23,7 @@ export function BlockPreview( { __experimentalPadding = 0, viewportWidth = 1200, __experimentalMinHeight, + __unstableIframeContentStyles, } ) { const originalSettings = useSelect( ( select ) => select( blockEditorStore ).getSettings(), @@ -45,6 +46,7 @@ export function BlockPreview( { viewportWidth={ viewportWidth } __experimentalPadding={ __experimentalPadding } __experimentalMinHeight={ __experimentalMinHeight } + __unstableIframeContentStyles={ __unstableIframeContentStyles } /> ); diff --git a/packages/block-editor/src/components/inserter/media-tab/media-list.js b/packages/block-editor/src/components/inserter/media-tab/media-list.js index a8b224788b47c..1f0e98aa35fda 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-list.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-list.js @@ -1,7 +1,6 @@ /** * WordPress dependencies */ -// import { useInstanceId } from '@wordpress/compose'; import { __unstableComposite as Composite, __unstableUseCompositeState as useCompositeState, @@ -49,6 +48,7 @@ function MediaPreview( { media, onClick, composite, mediaType } ) { From 8d062658c21a23924fe860983941098d6c77e9ab Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Thu, 24 Nov 2022 11:37:51 +0200 Subject: [PATCH 11/18] remove `BlockPreview` usage --- .../src/components/block-preview/auto.js | 15 ++++-------- .../src/components/block-preview/index.js | 2 -- .../inserter/media-tab/media-list.js | 21 ++++++++--------- .../inserter/media-tab/media-tab.js | 8 +++++-- .../components/inserter/media-tab/utils.js | 23 +++++++++++++++---- .../src/components/inserter/style.scss | 19 +++++---------- 6 files changed, 44 insertions(+), 44 deletions(-) diff --git a/packages/block-editor/src/components/block-preview/auto.js b/packages/block-editor/src/components/block-preview/auto.js index 3dad2954688d5..ddf4ee0ec75ab 100644 --- a/packages/block-editor/src/components/block-preview/auto.js +++ b/packages/block-editor/src/components/block-preview/auto.js @@ -25,7 +25,6 @@ function ScaledBlockPreview( { containerWidth, __experimentalPadding, __experimentalMinHeight, - __unstableIframeContentStyles, } ) { const [ contentResizeListener, { height: contentHeight } ] = useResizeObserver(); @@ -40,12 +39,8 @@ function ScaledBlockPreview( { // Avoid scrollbars for pattern previews. const editorStyles = useMemo( () => { - if ( ! styles && ! __unstableIframeContentStyles ) { - return; - } - let _editorStyles = []; if ( styles ) { - _editorStyles = [ + return [ ...styles, { css: 'body{height:auto;overflow:hidden;}', @@ -53,11 +48,9 @@ function ScaledBlockPreview( { }, ]; } - if ( __unstableIframeContentStyles ) { - _editorStyles.push( { css: __unstableIframeContentStyles } ); - } - return _editorStyles; - }, [ styles, __unstableIframeContentStyles ] ); + + return styles; + }, [ styles ] ); const svgFilters = useMemo( () => { return [ ...( duotone?.default ?? [] ), ...( duotone?.theme ?? [] ) ]; diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js index cd64e0de395fd..535a67438cad8 100644 --- a/packages/block-editor/src/components/block-preview/index.js +++ b/packages/block-editor/src/components/block-preview/index.js @@ -23,7 +23,6 @@ export function BlockPreview( { __experimentalPadding = 0, viewportWidth = 1200, __experimentalMinHeight, - __unstableIframeContentStyles, } ) { const originalSettings = useSelect( ( select ) => select( blockEditorStore ).getSettings(), @@ -46,7 +45,6 @@ export function BlockPreview( { viewportWidth={ viewportWidth } __experimentalPadding={ __experimentalPadding } __experimentalMinHeight={ __experimentalMinHeight } - __unstableIframeContentStyles={ __unstableIframeContentStyles } /> ); diff --git a/packages/block-editor/src/components/inserter/media-tab/media-list.js b/packages/block-editor/src/components/inserter/media-tab/media-list.js index 1f0e98aa35fda..2fe787bc6fdfa 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-list.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-list.js @@ -15,18 +15,17 @@ import { cloneBlock } from '@wordpress/blocks'; * Internal dependencies */ import InserterDraggableBlocks from '../../inserter-draggable-blocks'; -import BlockPreview from '../../block-preview'; -import { getBlockFromMedia } from './utils'; +import { getBlockAndPreviewFromMedia } from './utils'; function MediaPreview( { media, onClick, composite, mediaType } ) { - const blocks = useMemo( - () => getBlockFromMedia( media, mediaType ), + const [ block, preview ] = useMemo( + () => getBlockAndPreviewFromMedia( media, mediaType ), [ media, mediaType ] ); const title = media.title?.rendered || media.title; const baseCssClass = 'block-editor-inserter__media-list'; return ( - + { ( { draggable, onDragStart, onDragEnd } ) => (
{ - onClick( blocks ); + onClick( block ); } } aria-label={ title } > - +
+ { preview } +
diff --git a/packages/block-editor/src/components/inserter/media-tab/media-tab.js b/packages/block-editor/src/components/inserter/media-tab/media-tab.js index 855448882bdc9..78e09d36d0ae3 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-tab.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-tab.js @@ -29,7 +29,9 @@ import { MediaCategoryPanel } from './media-panel'; import MediaUploadCheck from '../../media-upload/check'; import MediaUpload from '../../media-upload'; import { useMediaCategories } from './hooks'; -import { getBlockFromMedia } from './utils'; +import { getBlockAndPreviewFromMedia } from './utils'; + +const ALLOWED_MEDIA_TYPES = [ 'image', 'video', 'audio' ]; function MediaTab( { rootClientId, @@ -45,7 +47,8 @@ function MediaTab( { if ( ! media?.url ) { return; } - onInsert( getBlockFromMedia( media, media.type ) ); + const [ block ] = getBlockAndPreviewFromMedia( media, media.type ); + onInsert( block ); }, [ onInsert ] ); @@ -90,6 +93,7 @@ function MediaTab( { ( diff --git a/packages/compose/src/hooks/use-focus-outside/index.ts b/packages/compose/src/hooks/use-focus-outside/index.ts index 8e6a9af749d77..0d62318d38eca 100644 --- a/packages/compose/src/hooks/use-focus-outside/index.ts +++ b/packages/compose/src/hooks/use-focus-outside/index.ts @@ -155,8 +155,15 @@ export default function useFocusOutside( // would be when we load modals that are not React components and // therefore don't exist in the React tree. An example is opening // the Media Library modal from another dialog. + // This attribute should contain a selector of the related target + // we want to ignore, because we still need to trigger the blur event + // on all other cases. + const ignoreForRelatedTarget = event.target.getAttribute( + 'data-unstable-ignore-focus-outside-for-relatedtarget' + ); if ( - event.target.hasAttribute( 'data-unstable-ignore-focus-outside' ) + ignoreForRelatedTarget && + event.relatedTarget?.closest( ignoreForRelatedTarget ) ) { return; } From 80fce4468d024425d8fc848fb6aeb76ef9260274 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Thu, 24 Nov 2022 17:05:08 +0200 Subject: [PATCH 14/18] Update packages/block-editor/src/components/inserter/media-tab/media-tab.js Co-authored-by: Matias Ventura --- .../block-editor/src/components/inserter/media-tab/media-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/inserter/media-tab/media-tab.js b/packages/block-editor/src/components/inserter/media-tab/media-tab.js index 677bdea01d3a1..639a63df271d0 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-tab.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-tab.js @@ -97,7 +97,7 @@ function MediaTab( { render={ ( { open } ) => (