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

ResizableBox: Add visual handles for side resizers #14543

Merged
merged 10 commits into from
Apr 12, 2019
2 changes: 1 addition & 1 deletion assets/stylesheets/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ $icon-button-size: 36px;
$icon-button-size-small: 24px;
$inserter-tabs-height: 36px;
$block-toolbar-height: $block-controls-height + $border-width;
$resize-handler-size: 16px;
$resize-handler-size: 15px;
$resize-handler-container-size: $resize-handler-size + ($grid-size-small * 2); // Make the resize handle container larger so there's a larger grabbable area.

// Blocks
Expand Down
6 changes: 5 additions & 1 deletion assets/stylesheets/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ $z-layers: (
".nux-dot-tip": 1000001,

// Show tooltips above NUX tips, wp-admin menus, submenus, and sidebar:
".components-tooltip": 1000002
".components-tooltip": 1000002,

// Make sure corner handles are above side handles for ResizableBox component
".components-resizable-box__side-handle": 1,
".components-resizable-box__corner-handle": 2
);

@function z-index( $key ) {
Expand Down
34 changes: 34 additions & 0 deletions packages/components/src/resizable-box/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ function ResizableBox( { className, ...props } ) {
};

const handleClassName = 'components-resizable-box__handle';
const sideHandleClassName = 'components-resizable-box__side-handle';
const cornerHandleClassName = 'components-resizable-box__corner-handle';

return (
<ReResizableBox
Expand All @@ -26,18 +28,46 @@ function ResizableBox( { className, ...props } ) {
handleClasses={ {
top: classnames(
handleClassName,
sideHandleClassName,
'components-resizable-box__handle-top',
),
right: classnames(
handleClassName,
sideHandleClassName,
'components-resizable-box__handle-right',
),
bottom: classnames(
handleClassName,
sideHandleClassName,
'components-resizable-box__handle-bottom',
),
left: classnames(
handleClassName,
sideHandleClassName,
'components-resizable-box__handle-left',
),
topLeft: classnames(
handleClassName,
cornerHandleClassName,
'components-resizable-box__handle-top',
'components-resizable-box__handle-left',
),
topRight: classnames(
handleClassName,
cornerHandleClassName,
'components-resizable-box__handle-top',
'components-resizable-box__handle-right',
),
bottomRight: classnames(
handleClassName,
cornerHandleClassName,
'components-resizable-box__handle-bottom',
'components-resizable-box__handle-right',
),
bottomLeft: classnames(
handleClassName,
cornerHandleClassName,
'components-resizable-box__handle-bottom',
'components-resizable-box__handle-left',
),
} }
Expand All @@ -46,6 +76,10 @@ function ResizableBox( { className, ...props } ) {
right: handleStylesOverrides,
bottom: handleStylesOverrides,
left: handleStylesOverrides,
topLeft: handleStylesOverrides,
topRight: handleStylesOverrides,
bottomRight: handleStylesOverrides,
bottomLeft: handleStylesOverrides,
} }
{ ...props }
/>
Expand Down
103 changes: 88 additions & 15 deletions packages/components/src/resizable-box/style.scss
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
// This is a wrapper of the actual visible handle (pseudo element). It is styled
// to be much bigger than the visual part so it's easier to click and use.
.components-resizable-box__handle {
display: none;
width: $resize-handler-container-size;
height: $resize-handler-container-size;

// Show the resize handle when selected.
.components-resizable-box__container.is-selected & {
display: block;
}

// The handle 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;
}

// This is the "visible" resize handle.
.components-resizable-box__handle::before {
// This is the "visible" resize handle - the circle part
.components-resizable-box__handle::after {
display: block;
content: "";
width: $resize-handler-size;
Expand All @@ -23,21 +21,96 @@
border-radius: 50%;
background: theme(primary);
cursor: inherit;
position: absolute;
top: calc(50% - #{ceil($resize-handler-size / 2)});
right: calc(50% - #{ceil($resize-handler-size / 2)});
}

// This is the "visible" resize handle for side handles - the line
.components-resizable-box__side-handle::before {
display: block;
content: "";
width: 7px;
height: 7px;
border: 2px solid $white;
background: theme(primary);
cursor: inherit;
position: absolute;
top: calc(50% - 4px);
right: calc(50% - 4px);
transition: transform 0.1s ease-in;
}

.is-dark-theme {
.components-resizable-box__side-handle::before,
.components-resizable-box__handle::after {
border-color: $light-gray-600;
}
}

// Show corner handles on top of side handles so they can be used
.components-resizable-box__side-handle {
z-index: z-index(".components-resizable-box__side-handle");
}

.components-resizable-box__corner-handle {
z-index: z-index(".components-resizable-box__corner-handle");
}

// Make horizontal side-handles full width
.components-resizable-box__side-handle.components-resizable-box__handle-top,
.components-resizable-box__side-handle.components-resizable-box__handle-bottom,
.components-resizable-box__side-handle.components-resizable-box__handle-top::before,
.components-resizable-box__side-handle.components-resizable-box__handle-bottom::before {
width: 100%;
left: 0;
border-left: 0;
border-right: 0;
}

// Make vertical side-handles full height
.components-resizable-box__side-handle.components-resizable-box__handle-left,
.components-resizable-box__side-handle.components-resizable-box__handle-right,
.components-resizable-box__side-handle.components-resizable-box__handle-left::before,
.components-resizable-box__side-handle.components-resizable-box__handle-right::before {
height: 100%;
top: 0;
border-top: 0;
border-bottom: 0;
}

// Hide side handle line by default
.components-resizable-box__side-handle.components-resizable-box__handle-top::before,
.components-resizable-box__side-handle.components-resizable-box__handle-bottom::before {
transform: scaleX(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple animation notes: Just noting that scale is one of the less performant animations. I don't think it's a huge issue here since we're only animating borders basically. Shouldn't have a huge impact.

In any case though, we should move these into an animation property and combine it with opacity animation as well so this animation relates a bit more to some of the other animations we have happening in the UI. Then we can also loop in the @reduce-motion mixin for users that want to opt out of the animation as well.

@marekhrabe I have that change ready locally — do you mind if I push it to this branch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have that change ready locally — do you mind if I push it to this branch?

You rock! Please do 🤘

}

.components-resizable-box__side-handle.components-resizable-box__handle-left::before,
.components-resizable-box__side-handle.components-resizable-box__handle-right::before {
transform: scaleY(0);
}

// Reveal the side handle line when hovered or in use
.components-resizable-box__side-handle:active::before,
.components-resizable-box__side-handle:hover::before {
transform: none;
transition: transform 0.1s ease-out;
}

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

.components-resizable-box__handle-bottom {
bottom: calc(#{$resize-handler-container-size / 2} * -1);
left: calc(50% - #{$resize-handler-container-size / 2});
}

.components-resizable-box__handle-left {
top: calc(50% - #{$resize-handler-container-size / 2});
left: calc(#{$resize-handler-container-size / 2} * -1);
}

.components-resizable-box__handle-top {
top: calc(#{$resize-handler-container-size / 2} * -1);
}

.components-resizable-box__handle-bottom {
bottom: calc(#{$resize-handler-container-size / 2} * -1);
}
/*!rtl:end:ignore*/