Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gallery Block: Add Media Library button to the upload new image area #12367

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/block-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## 2.0.0 (Unreleased)

### New Features

- Added the `addToGallery` property to the `MediaUpload` interface. The property allows users to open the media modal in the `gallery-library`instead of `gallery-edit` state.
- Added the `addToGallery` property to the `MediaPlaceholder` component. The component passes the property to the `MediaUpload` component used inside the placeholder.
- Added the `isAppender` property to the `MediaPlaceholder` component. The property changes the look of the placeholder to be adequate to scenarios where new files are added to an already existing set of files, e.g., adding files to a gallery.
- Added the `dropZoneUIOnly` property to the `MediaPlaceholder` component. The property makes the `MediaPlaceholder` only render a dropzone without any other additional UI.

### Breaking Changes

- `CopyHandler` will now only catch cut/copy events coming from its `props.children`, instead of from anywhere in the `document`.
Expand Down
288 changes: 213 additions & 75 deletions packages/block-editor/src/components/media-placeholder/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
/**
* External dependencies
*/
import { every, get, noop, startsWith, defaultTo } from 'lodash';
import {
defaultTo,
every,
get,
isArray,
noop,
startsWith,
} from 'lodash';
import classnames from 'classnames';

/**
Expand Down Expand Up @@ -103,8 +110,28 @@ export class MediaPlaceholder extends Component {
}

onFilesUpload( files ) {
const { onSelect, multiple, onError, allowedTypes, mediaUpload } = this.props;
const setMedia = multiple ? onSelect : ( [ media ] ) => onSelect( media );
const {
addToGallery,
allowedTypes,
mediaUpload,
multiple,
onError,
onSelect,
value = [],
} = this.props;
let setMedia;
if ( multiple ) {
if ( addToGallery ) {
const currentValue = value;
setMedia = ( newMedia ) => {
onSelect( currentValue.concat( newMedia ) );
};
} else {
setMedia = onSelect;
}
} else {
setMedia = ( [ media ] ) => onSelect( media );
}
mediaUpload( {
allowedTypes,
filesList: files,
Expand All @@ -121,42 +148,32 @@ export class MediaPlaceholder extends Component {
this.setState( { isURLInputVisible: false } );
}

render() {
renderPlaceholder( content, onClick ) {
const {
accept,
icon,
allowedTypes = [],
className,
hasUploadPermissions,
icon,
isAppender,
labels = {},
onSelect,
value = {},
onSelectURL,
onHTMLDrop = noop,
multiple = false,
notices,
allowedTypes = [],
hasUploadPermissions,
mediaUpload,
onSelectURL,
} = this.props;

const {
isURLInputVisible,
src,
} = this.state;

let instructions = labels.instructions || '';
let title = labels.title || '';
let instructions = labels.instructions;
let title = labels.title;

if ( ! hasUploadPermissions && ! onSelectURL ) {
instructions = __( 'To edit this block, you need permission to upload media.' );
}

if ( ! instructions || ! title ) {
if ( instructions === undefined || title === undefined ) {
const isOneType = 1 === allowedTypes.length;
const isAudio = isOneType && 'audio' === allowedTypes[ 0 ];
const isImage = isOneType && 'image' === allowedTypes[ 0 ];
const isVideo = isOneType && 'video' === allowedTypes[ 0 ];

if ( ! instructions ) {
if ( instructions === undefined ) {
if ( hasUploadPermissions ) {
instructions = __( 'Drag a media file, upload a new one or select a file from your library.' );

Expand All @@ -180,7 +197,7 @@ export class MediaPlaceholder extends Component {
}
}

if ( ! title ) {
if ( title === undefined ) {
title = __( 'Media' );

if ( isAudio ) {
Expand All @@ -193,70 +210,191 @@ export class MediaPlaceholder extends Component {
}
}

const placeholderClassName = classnames(
'block-editor-media-placeholder',
'editor-media-placeholder',
className,
{ 'is-appender': isAppender }
);

return (
<Placeholder
icon={ icon }
label={ title }
instructions={ instructions }
className={ classnames( 'editor-media-placeholder block-editor-media-placeholder', className ) }
className={ placeholderClassName }
notices={ notices }
onClick={ onClick }
>
<MediaUploadCheck>
{ !! mediaUpload && (
<Fragment>
<DropZone
onFilesDrop={ this.onFilesUpload }
onHTMLDrop={ onHTMLDrop }
/>
<FormFileUpload
isLarge
className="editor-media-placeholder__button block-editor-media-placeholder__button"
onChange={ this.onUpload }
accept={ accept }
multiple={ multiple }
>
{ __( 'Upload' ) }
</FormFileUpload>
</Fragment>
) }
<MediaUpload
gallery={ multiple && this.onlyAllowsImages() }
multiple={ multiple }
onSelect={ onSelect }
allowedTypes={ allowedTypes }
value={ value.id }
render={ ( { open } ) => (
<Button
isLarge
className="editor-media-placeholder__button block-editor-media-placeholder__button"
onClick={ open }
>
{ __( 'Media Library' ) }
</Button>
) }
{ content }
</Placeholder>
);
}

renderDropZone() {
const { onHTMLDrop = noop } = this.props;
return (
<DropZone
onFilesDrop={ this.onFilesUpload }
onHTMLDrop={ onHTMLDrop }
/>
);
}

renderUrlSelectionUI() {
const {
onSelectURL,
} = this.props;
if ( ! onSelectURL ) {
return null;
}
const {
isURLInputVisible,
src,
} = this.state;
return (
<div className="editor-media-placeholder__url-input-container block-editor-media-placeholder__url-input-container">
<Button
className="editor-media-placeholder__button block-editor-media-placeholder__button"
onClick={ this.openURLInput }
isToggled={ isURLInputVisible }
isLarge
>
{ __( 'Insert from URL' ) }
</Button>
{ isURLInputVisible && (
<InsertFromURLPopover
src={ src }
onChange={ this.onChangeSrc }
onSubmit={ this.onSubmitSrc }
onClose={ this.closeURLInput }
/>
</MediaUploadCheck>
{ onSelectURL && (
<div className="editor-media-placeholder__url-input-container block-editor-media-placeholder__url-input-container">
) }
</div>
);
}

renderMediaUploadChecked() {
const {
accept,
addToGallery,
allowedTypes = [],
isAppender,
mediaUpload,
multiple = false,
onSelect,
value = {},
} = this.props;

const mediaLibraryButton = (
<MediaUpload
addToGallery={ addToGallery }
gallery={ multiple && this.onlyAllowsImages() }
multiple={ multiple }
onSelect={ onSelect }
allowedTypes={ allowedTypes }
value={
isArray( value ) ?
value.map( ( { id } ) => id ) :
value.id
}
render={ ( { open } ) => {
return (
<Button
className="editor-media-placeholder__button block-editor-media-placeholder__button"
onClick={ this.openURLInput }
isToggled={ isURLInputVisible }
isLarge
className={ classnames(
'editor-media-placeholder__button',
'editor-media-placeholder__media-library-button'
) }
onClick={ ( event ) => {
event.stopPropagation();
open();
} }
>
{ __( 'Insert from URL' ) }
{ __( 'Media Library' ) }
</Button>
{ isURLInputVisible && (
<InsertFromURLPopover
src={ src }
onChange={ this.onChangeSrc }
onSubmit={ this.onSubmitSrc }
onClose={ this.closeURLInput }
/>
);
} }
/>
);

if ( mediaUpload && isAppender ) {
return (
<Fragment>
{ this.renderDropZone() }
<FormFileUpload
onChange={ this.onUpload }
accept={ accept }
multiple={ multiple }
render={ ( { openFileDialog } ) => {
const content = (
<Fragment>
<IconButton
isLarge
className={ classnames(
'block-editor-media-placeholder__button',
'editor-media-placeholder__button',
'block-editor-media-placeholder__upload-button'
) }
icon="upload"
>
{ __( 'Upload' ) }
</IconButton>
{ mediaLibraryButton }
{ this.renderUrlSelectionUI() }
</Fragment>
);
return this.renderPlaceholder( content, openFileDialog );
} }
/>
</Fragment>
);
}
if ( mediaUpload ) {
const content = (
<Fragment>
{ this.renderDropZone() }
<FormFileUpload
isLarge
className={ classnames(
'block-editor-media-placeholder__button',
'editor-media-placeholder__button',
'block-editor-media-placeholder__upload-button'
) }
</div>
) }
</Placeholder>
onChange={ this.onUpload }
accept={ accept }
multiple={ multiple }
>
{ __( 'Upload' ) }
</FormFileUpload>
{ mediaLibraryButton }
{ this.renderUrlSelectionUI() }
</Fragment>
);
return this.renderPlaceholder( content );
}
return this.renderPlaceholder( mediaLibraryButton );
}

render() {
const {
dropZoneUIOnly,
} = this.props;

if ( dropZoneUIOnly ) {
return (
<MediaUploadCheck>
{ this.renderDropZone() }
</MediaUploadCheck>
);
}

return (
<MediaUploadCheck
fallback={ this.renderPlaceholder( this.renderUrlSelectionUI() ) }
>
{ this.renderMediaUploadChecked() }
</MediaUploadCheck>
);
}
}
Expand Down
27 changes: 27 additions & 0 deletions packages/block-editor/src/components/media-placeholder/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,30 @@
.components-form-file-upload .block-editor-media-placeholder__button {
margin-right: $grid-size-small;
}

.block-editor-media-placeholder.is-appender {
min-height: 100px;
outline: $border-width dashed $dark-gray-150;

&:hover {
outline: $border-width dashed $dark-gray-500;
cursor: pointer;
}

.is-dark-theme & {

&:hover {
outline: $border-width dashed $white;
}
}

.block-editor-media-placeholder__upload-button {
margin-right: $grid-size-small;
&.components-button:hover,
&.components-button:focus {
box-shadow: none;
border: $border-width solid $dark-gray-500;
}
}

}
Loading