diff --git a/blocks/library/image/block.js b/blocks/library/image/block.js index 7629ab5c58f0e..78e436c48585b 100644 --- a/blocks/library/image/block.js +++ b/blocks/library/image/block.js @@ -4,11 +4,12 @@ import classnames from 'classnames'; import ResizableBox from 're-resizable'; import { - startCase, + find, + get, isEmpty, map, - get, pick, + startCase, } from 'lodash'; /** @@ -18,9 +19,12 @@ import { __ } from '@wordpress/i18n'; import { Component, compose } from '@wordpress/element'; import { getBlobByURL, revokeBlobURL, viewPort } from '@wordpress/utils'; import { + Button, + ButtonGroup, IconButton, PanelBody, SelectControl, + TextControl, TextareaControl, Toolbar, } from '@wordpress/components'; @@ -55,6 +59,9 @@ class ImageBlock extends Component { this.onSelectImage = this.onSelectImage.bind( this ); this.onSetHref = this.onSetHref.bind( this ); this.updateImageURL = this.updateImageURL.bind( this ); + this.updateWidth = this.updateWidth.bind( this ); + this.updateHeight = this.updateHeight.bind( this ); + this.updateDimensions = this.updateDimensions.bind( this ); this.state = { captionFocused: false, @@ -98,7 +105,11 @@ class ImageBlock extends Component { } onSelectImage( media ) { - this.props.setAttributes( pick( media, [ 'alt', 'id', 'caption', 'url' ] ) ); + this.props.setAttributes( { + ...pick( media, [ 'alt', 'id', 'caption', 'url' ] ), + width: undefined, + height: undefined, + } ); } onSetHref( value ) { @@ -133,7 +144,21 @@ class ImageBlock extends Component { } updateImageURL( url ) { - this.props.setAttributes( { url } ); + this.props.setAttributes( { url, width: undefined, height: undefined } ); + } + + updateWidth( width ) { + this.props.setAttributes( { width: parseInt( width, 10 ) } ); + } + + updateHeight( height ) { + this.props.setAttributes( { height: parseInt( height, 10 ) } ); + } + + updateDimensions( width = undefined, height = undefined ) { + return () => { + this.props.setAttributes( { width, height } ); + }; } getAvailableSizes() { @@ -144,10 +169,6 @@ class ImageBlock extends Component { const { attributes, setAttributes, isSelected, className, settings, toggleSelection } = this.props; const { url, alt, caption, align, id, href, width, height } = attributes; - const availableSizes = this.getAvailableSizes(); - const figureStyle = width ? { width } : {}; - const isResizable = [ 'wide', 'full' ].indexOf( align ) === -1 && ( ! viewPort.isExtraSmall() ); - const controls = ( isSelected && ( @@ -176,7 +197,10 @@ class ImageBlock extends Component { ) ); - if ( ! url ) { + const availableSizes = this.getAvailableSizes(); + const selectedSize = find( availableSizes, ( size ) => size.source_url === url ); + + if ( ! url || ! selectedSize ) { return [ controls, { ! isEmpty( availableSizes ) && ( ( { value: size.source_url, @@ -220,10 +245,61 @@ class ImageBlock extends Component { onChange={ this.updateImageURL } /> ) } +
+

+ { __( 'Image Dimensions' ) } +

+
+ + +
+
+ + { [ 25, 50, 75, 100 ].map( ( scale ) => { + const scaledWidth = Math.round( selectedSize.width * ( scale / 100 ) ); + const scaledHeight = Math.round( selectedSize.height * ( scale / 100 ) ); + + const isCurrent = width === scaledWidth && height === scaledHeight; + + return ( + + ); + } ) } + + +
+
), -
+
{ ( sizes ) => { const { @@ -239,7 +315,11 @@ class ImageBlock extends Component { const img = {; if ( ! isResizable || ! imageWidthWithinContainer ) { - return img; + return ( +
+ { img } +
+ ); } const currentWidth = width || imageWidthWithinContainer; diff --git a/blocks/library/image/editor.scss b/blocks/library/image/editor.scss index db51468bc901e..826b1c103d827 100644 --- a/blocks/library/image/editor.scss +++ b/blocks/library/image/editor.scss @@ -7,6 +7,10 @@ width: 100%; } + &.is-resized img { + height: 100%; + } + &.is-transient img { @include loading_fade; } @@ -92,3 +96,30 @@ margin-right: auto; } } + +.edit-post-sidebar .blocks-image__dimensions { + margin-bottom: 1em; + + .blocks-image__dimensions__row { + display: flex; + justify-content: space-between; + + .blocks-image__dimensions__width, + .blocks-image__dimensions__height { + margin-bottom: 0.5em; + + // Fix the text and placeholder text being misaligned in Safari + input { + line-height: 1.25; + } + } + + .blocks-image__dimensions__width { + margin-right: 5px; + } + + .blocks-image__dimensions__height { + margin-left: 5px; + } + } +} diff --git a/blocks/library/paragraph/editor.scss b/blocks/library/paragraph/editor.scss index a7a87b0415126..a93686fa68e21 100644 --- a/blocks/library/paragraph/editor.scss +++ b/blocks/library/paragraph/editor.scss @@ -1,6 +1,7 @@ .blocks-font-size__main { display: flex; justify-content: space-between; + margin-bottom: 1em; } .blocks-paragraph__custom-size-slider { diff --git a/components/button-group/style.scss b/components/button-group/style.scss index 5be7e700ac197..3634833e5b606 100644 --- a/components/button-group/style.scss +++ b/components/button-group/style.scss @@ -1,6 +1,5 @@ .components-button-group { display: inline-block; - margin-bottom: 20px; .components-button { border-radius: 0; diff --git a/components/button/index.js b/components/button/index.js index 49713d398a824..26d576b78d47e 100644 --- a/components/button/index.js +++ b/components/button/index.js @@ -47,7 +47,7 @@ class Button extends Component { ...additionalProps } = this.props; const classes = classnames( 'components-button', className, { - button: ( isPrimary || isLarge ), + button: ( isPrimary || isLarge || isSmall ), 'button-primary': isPrimary, 'button-large': isLarge, 'button-small': isSmall, diff --git a/components/button/test/index.js b/components/button/test/index.js index 2d3582ae8b82c..089d40721ec98 100644 --- a/components/button/test/index.js +++ b/components/button/test/index.js @@ -38,7 +38,7 @@ describe( 'Button', () => { it( 'should render a button element with button-small class', () => { const button = shallow(