Skip to content

Commit

Permalink
Add caption to gallery images (#4199)
Browse files Browse the repository at this point in the history
Made gallery to image and image to gallery transformations take into consideration caption attributes.
Implemented caption editing and styles in the gallery block.
Added caption to the attributes of images in the gallery and to the saving logic.
Added caption slimImageObject set of MediaUploadButton.
  • Loading branch information
jorgefilipecosta authored Feb 6, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 69830a1 commit ba87962
Showing 8 changed files with 102 additions and 14 deletions.
33 changes: 30 additions & 3 deletions blocks/library/gallery/block.js
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@ class GalleryBlock extends Component {
constructor() {
super( ...arguments );

this.onFocusImageCaption = this.onFocusImageCaption.bind( this );
this.onSelectImage = this.onSelectImage.bind( this );
this.onSelectImages = this.onSelectImages.bind( this );
this.setLinkTo = this.setLinkTo.bind( this );
@@ -55,10 +56,27 @@ class GalleryBlock extends Component {
}

onSelectImage( index ) {
return () => {
return ( event ) => {
// ignore clicks in the editable caption.
// Without this logic, text operations like selection, select / unselects the images.
if ( event.target.tagName === 'FIGCAPTION' ) {
return;
}
this.setState( ( state ) => ( {
selectedImage: index === state.selectedImage ? null : index,
} ) );

// unfocus currently focus editable
this.props.setFocus( { ...this.props.focus, editableIndex: undefined } );
};
}

onFocusImageCaption( index ) {
return ( focusValue ) => {
this.setState( {
selectedImage: index,
} );
this.props.setFocus( { editableIndex: index, ...focusValue } );
};
}

@@ -73,8 +91,13 @@ class GalleryBlock extends Component {
};
}

onSelectImages( imgs ) {
this.props.setAttributes( { images: imgs } );
onSelectImages( images ) {
this.props.setAttributes( {
images: images.map( ( attributes ) => ( {
...attributes,
caption: attributes.caption ? [ attributes.caption ] : [],
} ) ),
} );
}

setLinkTo( value ) {
@@ -220,6 +243,10 @@ class GalleryBlock extends Component {
onRemove={ this.onRemoveImage( index ) }
onClick={ this.onSelectImage( index ) }
setAttributes={ ( attrs ) => this.setImageAttributes( index, attrs ) }
caption={ img.caption }
focus={ focus }
onFocus={ this.onFocusImageCaption( index ) }
imageIndex={ index }
/>
</li>
) ) }
20 changes: 19 additions & 1 deletion blocks/library/gallery/editor.scss
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
}

.blocks-gallery-item {
position: relative;

.is-selected {
outline: 4px solid $blue-medium-500;
@@ -13,6 +12,25 @@
&.is-transient img {
@include loading_fade;
}

.blocks-rich-text {
position: absolute;
width: 100%;
}

// last-of-type is used because RichText creates to figcations when placeholders are visible,
// and in that case only the second one should be targeted.
// Using data-is-placeholder-visible caused blinks because the attributes are not immediately added to the dom.
.blocks-rich-text figcaption:last-of-type {
position: relative;
}

.is-selected .blocks-rich-text {
width: calc( 100% - 8px );
left: 4px;
margin-top: -4px;
}

}

.blocks-gallery-item__inline-menu {
18 changes: 17 additions & 1 deletion blocks/library/gallery/gallery-image.js
Original file line number Diff line number Diff line change
@@ -10,6 +10,11 @@ import { Component } from '@wordpress/element';
import { IconButton, withAPIData, Spinner } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import RichText from '../../rich-text';

class GalleryImage extends Component {
componentWillReceiveProps( { image } ) {
if ( image && image.data && ! this.props.url ) {
@@ -21,7 +26,7 @@ class GalleryImage extends Component {
}

render() {
const { url, alt, id, linkTo, link, isSelected, onClick, onRemove } = this.props;
const { url, alt, id, linkTo, link, imageIndex, isSelected, caption, onClick, onRemove, focus, setAttributes, onFocus } = this.props;

let href;

@@ -56,6 +61,17 @@ class GalleryImage extends Component {
</div>
}
{ href ? <a href={ href }>{ img }</a> : img }
{ ( caption && caption.length > 0 ) || ( focus && isSelected ) ? (
<RichText
tagName="figcaption"
placeholder={ __( 'Write caption…' ) }
value={ caption }
focus={ focus && focus.editableIndex === imageIndex ? focus : undefined }
onFocus={ onFocus }
onChange={ newCaption => setAttributes( { caption: newCaption } ) }
inlineToolbar
/>
) : null }
</figure>
);
/* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */
15 changes: 12 additions & 3 deletions blocks/library/gallery/index.js
Original file line number Diff line number Diff line change
@@ -26,10 +26,11 @@ const blockAttributes = {
type: 'array',
default: [],
source: 'query',
selector: 'ul.wp-block-gallery .blocks-gallery-item img',
selector: 'ul.wp-block-gallery .blocks-gallery-item',
query: {
url: {
source: 'attribute',
selector: 'img',
attribute: 'src',
},
link: {
@@ -38,13 +39,20 @@ const blockAttributes = {
},
alt: {
source: 'attribute',
selector: 'img',
attribute: 'alt',
default: '',
},
id: {
source: 'attribute',
selector: 'img',
attribute: 'data-id',
},
caption: {
type: 'array',
source: 'children',
selector: 'figcaption',
},
},
},
columns: {
@@ -80,7 +88,7 @@ export const settings = {
const validImages = filter( attributes, ( { id, url } ) => id && url );
if ( validImages.length > 0 ) {
return createBlock( 'core/gallery', {
images: validImages.map( ( { id, url, alt } ) => ( { id, url, alt } ) ),
images: validImages.map( ( { id, url, alt, caption } ) => ( { id, url, alt, caption } ) ),
} );
}
return createBlock( 'core/gallery' );
@@ -149,7 +157,7 @@ export const settings = {
blocks: [ 'core/image' ],
transform: ( { images } ) => {
if ( images.length > 0 ) {
return images.map( ( { id, url, alt } ) => createBlock( 'core/image', { id, url, alt } ) );
return images.map( ( { id, url, alt, caption } ) => createBlock( 'core/image', { id, url, alt, caption } ) );
}
return createBlock( 'core/image' );
},
@@ -188,6 +196,7 @@ export const settings = {
<li key={ image.id || image.url } className="blocks-gallery-item">
<figure>
{ href ? <a href={ href }>{ img }</a> : img }
{ image.caption && image.caption.length > 0 && <figcaption>{ image.caption }</figcaption> }
</figure>
</li>
);
16 changes: 15 additions & 1 deletion blocks/library/gallery/style.scss
Original file line number Diff line number Diff line change
@@ -13,17 +13,31 @@
flex-grow: 1;
flex-direction: column;
justify-content: center;
position: relative;


figure {
height: 100%;
margin: 0;
height: 100%;
display: flex;
align-items: flex-end;
}

img {
display: block;
max-width: 100%;
height: auto;
}

figcaption {
padding-top: 3px;
color: $white;
text-align: center;
font-size: $default-font-size;
background-color: rgba($color: $black, $alpha: 0.7);
position: absolute;
width: 100%;
}
}

// Cropped
2 changes: 1 addition & 1 deletion blocks/media-upload/index.js
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ const getGalleryDetailsMediaFrame = () => {
// the media library image object contains numerous attributes
// we only need this set to display the image in the library
const slimImageObject = ( img ) => {
const attrSet = [ 'sizes', 'mime', 'type', 'subtype', 'id', 'url', 'alt', 'link' ];
const attrSet = [ 'sizes', 'mime', 'type', 'subtype', 'id', 'url', 'alt', 'link', 'caption' ];
return pick( img, attrSet );
};

6 changes: 4 additions & 2 deletions blocks/test/fixtures/core__gallery.json
Original file line number Diff line number Diff line change
@@ -8,11 +8,13 @@
"images": [
{
"url": "https://cldup.com/uuUqE_dXzy.jpg",
"alt": "title"
"alt": "title",
"caption": []
},
{
"url": "http://google.com/hi.png",
"alt": "title"
"alt": "title",
"caption": []
}
],
"imageCrop": true,
6 changes: 4 additions & 2 deletions blocks/test/fixtures/core__gallery__columns.json
Original file line number Diff line number Diff line change
@@ -8,11 +8,13 @@
"images": [
{
"url": "https://cldup.com/uuUqE_dXzy.jpg",
"alt": "title"
"alt": "title",
"caption": []
},
{
"url": "http://google.com/hi.png",
"alt": "title"
"alt": "title",
"caption": []
}
],
"columns": 1,

0 comments on commit ba87962

Please sign in to comment.