Skip to content

Commit

Permalink
Introduce a ResizableBox component (#10347)
Browse files Browse the repository at this point in the history
* Introduce a ResizableBox component and apply to image/spacer blocks

* Add a shared class to all drag handles to simplify CSS selectors

* Add additional documentation and an example

* chore: Tweak docs

* Add changelog comment and update readme

* Removed a stray "the"

* s/5.0.0/4.1.0/g
  • Loading branch information
chrisvanpatten committed Oct 7, 2018
1 parent 7ec834b commit eafd620
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 125 deletions.
26 changes: 0 additions & 26 deletions edit-post/assets/stylesheets/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -326,29 +326,3 @@
// icon standards.
margin-right: 2px;
}


/**
* Styles for resize handles
*/

@mixin resize-handler__container() {
display: none;

// The handle itself is a pseudo element, and will sit inside this larger
// container size.
width: $resize-handler-container-size;
height: $resize-handler-container-size;
padding: $grid-size-small;
}

@mixin resize-handler__visible-handle() {
display: block;
content: "";
width: $resize-handler-size;
height: $resize-handler-size;
border: 2px solid $white;
border-radius: 50%;
background: theme(primary);
cursor: inherit;
}
1 change: 0 additions & 1 deletion packages/block-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"moment": "^2.22.1",
"querystring": "^0.2.0",
"querystringify": "^1.0.0",
"re-resizable": "^4.7.1",
"url": "^0.11.0"
},
"devDependencies": {
Expand Down
23 changes: 1 addition & 22 deletions packages/block-library/src/image/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* External dependencies
*/
import classnames from 'classnames';
import ResizableBox from 're-resizable';
import {
get,
isEmpty,
Expand All @@ -22,6 +21,7 @@ import {
ButtonGroup,
IconButton,
PanelBody,
ResizableBox,
SelectControl,
TextControl,
TextareaControl,
Expand Down Expand Up @@ -446,21 +446,10 @@ class ImageEdit extends Component {
}
/* eslint-enable no-lonely-if */

// Removes the inline styles in the drag handles.
const handleStylesOverrides = {
width: null,
height: null,
top: null,
right: null,
bottom: null,
left: null,
};

return (
<Fragment>
{ getInspectorControls( imageWidth, imageHeight ) }
<ResizableBox
className="block-library-image__resizer"
size={
width && height ? {
width,
Expand All @@ -472,16 +461,6 @@ class ImageEdit extends Component {
minHeight={ minHeight }
maxHeight={ maxWidth / ratio }
lockAspectRatio
handleClasses={ {
right: 'block-library-image__resize-handler-right',
bottom: 'block-library-image__resize-handler-bottom',
left: 'block-library-image__resize-handler-left',
} }
handleStyles={ {
right: handleStylesOverrides,
bottom: handleStylesOverrides,
left: handleStylesOverrides,
} }
enable={ {
top: false,
right: showRightHandle,
Expand Down
47 changes: 8 additions & 39 deletions packages/block-library/src/image/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,20 @@
}

// This is necessary for the editor resize handles to accurately work on a non-floated, non-resized, small image.
.wp-block-image {
.block-library-image__resizer {
display: inline-block;
.wp-block-image .components-resizable-box__container {
display: inline-block;

img {
display: block;
width: 100%;
}
}
}

.block-library-image__resize-handler-right,
.block-library-image__resize-handler-bottom,
.block-library-image__resize-handler-left {
@include resize-handler__container();

.wp-block-image.is-focused & {
img {
display: block;
z-index: z-index(".block-library-image__resize-handlers");
width: 100%;
}
}

// Draw the visible handle
.block-library-image__resize-handler-right::before,
.block-library-image__resize-handler-bottom::before,
.block-library-image__resize-handler-left::before {
@include resize-handler__visible-handle();
}

/*!rtl:begin:ignore*/
.block-library-image__resize-handler-right {
top: calc(50% - #{$resize-handler-container-size / 2});
right: calc(#{$resize-handler-container-size / 2} * -1);
}

.block-library-image__resize-handler-left {
top: calc(50% - #{$resize-handler-container-size / 2});
left: calc(#{$resize-handler-container-size / 2} * -1);
}

.block-library-image__resize-handler-bottom {
bottom: calc(#{$resize-handler-container-size / 2} * -1);
left: calc(50% - #{$resize-handler-container-size / 2});
// Ensure the resize handles are visible when the image is focused.
.wp-block-image.is-focused .components-resizable-box__handle {
display: block;
z-index: z-index(".block-library-image__resize-handlers");
}
/*!rtl:end:ignore*/

.editor-block-list__block[data-type="core/image"][data-align="center"] {
.wp-block-image {
Expand Down
19 changes: 0 additions & 19 deletions packages/block-library/src/spacer/editor.scss
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
.block-library-spacer__resize-container.is-selected {
.block-library-spacer__resize-handler-bottom {
display: block;
}
}

.block-library-spacer__resize-container.is-selected {
background: $light-gray-200;
}

.block-library-spacer__resize-handler-bottom {
@include resize-handler__container();

// Offset the handle container's position.
position: absolute;
bottom: calc(#{$resize-handler-container-size / 2} * -1);
left: calc(50% - #{$resize-handler-container-size / 2});
}

.block-library-spacer__resize-handler-bottom::before {
@include resize-handler__visible-handle();
}
19 changes: 1 addition & 18 deletions packages/block-library/src/spacer/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* External dependencies
*/
import ResizableBox from 're-resizable';
import classnames from 'classnames';

/**
Expand All @@ -10,7 +9,7 @@ import classnames from 'classnames';
import { Fragment } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { InspectorControls } from '@wordpress/editor';
import { BaseControl, PanelBody } from '@wordpress/components';
import { BaseControl, PanelBody, ResizableBox } from '@wordpress/components';
import { withInstanceId } from '@wordpress/compose';

export const name = 'core/spacer';
Expand All @@ -36,16 +35,6 @@ export const settings = {
const { height } = attributes;
const id = `block-spacer-height-input-${ instanceId }`;

// Removes the inline styles in the drag handles.
const handleStylesOverrides = {
width: null,
height: null,
top: null,
right: null,
bottom: null,
left: null,
};

return (
<Fragment>
<ResizableBox
Expand All @@ -57,12 +46,6 @@ export const settings = {
height,
} }
minHeight="20"
handleClasses={ {
bottom: 'block-library-spacer__resize-handler-bottom',
} }
handleStyles={ {
bottom: handleStylesOverrides,
} }
enable={ {
top: false,
right: false,
Expand Down
6 changes: 6 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 4.1.0 (Unreleased)

### New Feature

- Added a new `ResizableBox` component.

## 4.0.0 (2018-09-30)

### Breaking Change
Expand Down
1 change: 1 addition & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"memize": "^1.0.5",
"moment": "^2.22.1",
"mousetrap": "^1.6.2",
"re-resizable": "^4.7.1",
"react-click-outside": "^2.3.1",
"react-color": "^2.13.4",
"react-datepicker": "^1.4.1",
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export { default as Popover } from './popover';
export { default as QueryControls } from './query-controls';
export { default as RadioControl } from './radio-control';
export { default as RangeControl } from './range-control';
export { default as ResizableBox } from './resizable-box';
export { default as ResponsiveWrapper } from './responsive-wrapper';
export { default as SandBox } from './sandbox';
export { default as SelectControl } from './select-control';
Expand Down
55 changes: 55 additions & 0 deletions packages/components/src/resizable-box/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# ResizableBox

ResizableBox is a wrapper around the [re-resizable package](https://github.com/bokuweb/re-resizable) with pre-defined classes and styles.

## Usage

Most options are passed directly through to [re-resizable](https://github.com/bokuweb/re-resizable) so you may wish to refer to their documentation. The primary differences in this component are that we set `handleClasses` (to use custom class names) and pass some null values to `handleStyles` (to unset some inline styles).

The example below shows how you might use `ResizableBox` to set a width and height inside a block's `edit` component.

```jsx
import { ResizableBox } from '@wordpress/components';

const Edit = ( props ) => {
const {
attributes: {
height,
width,
},
setAttributes,
toggleSelection,
} = props;

return (
<ResizableBox
size={ {
height,
width,
} }
minHeight="50"
minWidth="50"
enable={ {
top: false,
right: true,
bottom: true,
left: false,
topRight: false,
bottomRight: true,
bottomLeft: false,
topLeft: false,
} }
onResizeStop={ ( event, direction, elt, delta ) => {
setAttributes( {
height: parseInt( height + delta.height, 10 ),
width: parseInt( width + delta.width, 10 ),
} );
toggleSelection( true );
} }
onResizeStart={ () => {
toggleSelection( false );
} }
/>
);
}
```
55 changes: 55 additions & 0 deletions packages/components/src/resizable-box/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* External dependencies
*/
import classnames from 'classnames';
import ReResizableBox from 're-resizable';

function ResizableBox( { className, ...props } ) {
// Removes the inline styles in the drag handles.
const handleStylesOverrides = {
width: null,
height: null,
top: null,
right: null,
bottom: null,
left: null,
};

const handleClassName = 'components-resizable-box__handle';

return (
<ReResizableBox
className={ classnames(
'components-resizable-box__container',
className,
) }
handleClasses={ {
top: classnames(
handleClassName,
'components-resizable-box__handle-top',
),
right: classnames(
handleClassName,
'components-resizable-box__handle-right',
),
bottom: classnames(
handleClassName,
'components-resizable-box__handle-bottom',
),
left: classnames(
handleClassName,
'components-resizable-box__handle-left',
),
} }
handleStyles={ {
top: handleStylesOverrides,
right: handleStylesOverrides,
bottom: handleStylesOverrides,
left: handleStylesOverrides,
} }
{ ...props }
/>
);
}

export default ResizableBox;
Loading

0 comments on commit eafd620

Please sign in to comment.