Skip to content

Commit

Permalink
fix: resizable-box support horizontal and vertical dragging (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
BoBoooooo committed Oct 31, 2023
1 parent 70fc6f8 commit fd2fa94
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 19 deletions.
3 changes: 2 additions & 1 deletion packages/designer/src/sidebar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export * from './components-panel';
export * from './dependency-panel';
export * from './history-panel';
export * from './variable-panel';
export * from './sidebar';
export * from './sidebar';
export * from './resizable-box';
89 changes: 71 additions & 18 deletions packages/designer/src/sidebar/resizable-box.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,98 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import cx from 'classnames';
import { Box, HTMLCoralProps, css } from 'coral-system';
import { Resizable } from 'react-resizable';
import { Resizable, ResizeHandle } from 'react-resizable';

const resizeHandleStyle = css`
export interface ResizableBoxProps extends HTMLCoralProps<'div'> {
width?: number;
height?: number;
resizeHandlePosition?: 'left' | 'right' | 'top' | 'bottom';
axis?: 'x' | 'y';
}

const resizeHandleStyle = (axis: ResizableBoxProps['axis'], barStyle: HTMLCoralProps<'div'>) => css`
position: absolute;
top: 0;
z-index: 999;
width: 4px;
height: 100%;
cursor: col-resize;
cursor: ${axis === 'x' ? 'col-resize' : 'row-resize'};
${barStyle &&
Object.keys(barStyle)
.map((key) => `${key}: ${barStyle[key]};`)
.join('')}
&:hover,
&:active {
background-color: var(--tango-colors-brand);
}
`;

export interface ResizableBoxProps extends HTMLCoralProps<'div'> {
width?: number;
height?: number;
resizeHandlePosition?: 'left' | 'right';
}
const getResizeHandles = (
resizeHandlePosition: ResizableBoxProps['resizeHandlePosition'],
axis: ResizableBoxProps['axis'],
) => {
const handles: ResizeHandle[] = [];
switch (axis) {
case 'x':
handles.push(resizeHandlePosition === 'right' ? 'e' : 'w');
break;
case 'y':
handles.push(resizeHandlePosition === 'bottom' ? 's' : 'n');
break;
default:
break;
}
return handles;
};

export function ResizableBox({
resizeHandlePosition = 'right',
width: widthProp,
height,
height: heightProp,
children,
className,
style,
axis = 'x',
}: ResizableBoxProps) {
const [width, setWidth] = useState(widthProp);
const barStyle = resizeHandlePosition === 'right' ? { right: '-4px' } : { left: '-4px' };
const [height, setHeight] = useState(heightProp);

const barStyle: HTMLCoralProps<'div'> = {
...(axis === 'x'
? {
height: '100%',
width: '4px',
top: '0',
[resizeHandlePosition === 'right' ? 'right' : 'left']: '-4px',
}
: {
height: '4px',
width: '100%',
left: '0',
[resizeHandlePosition === 'bottom' ? 'bottom' : 'top']: '0',
}),
};

useEffect(() => {
setWidth(widthProp);
}, [widthProp]);

useEffect(() => {
setHeight(heightProp);
}, [heightProp]);

return (
<Resizable
axis="x"
axis={axis}
width={width}
resizeHandles={getResizeHandles(resizeHandlePosition, axis)}
height={height}
minConstraints={[150, 150]}
maxConstraints={[window.innerWidth * 0.6, window.innerHeight * 0.8]}
onResize={(e, { size }) => {
setWidth(size.width);
if (axis === 'x') {
setWidth(size.width);
}
if (axis === 'y') {
setHeight(size.height);
}
}}
onResizeStart={() => {
document.body.style.pointerEvents = 'none';
Expand All @@ -49,7 +102,7 @@ export function ResizableBox({
document.body.style.pointerEvents = 'auto';
document.body.style.userSelect = 'auto';
}}
handle={<Box className="ResizeHandle" css={resizeHandleStyle} {...barStyle} />}
handle={<Box className="ResizeHandle" css={resizeHandleStyle(axis, barStyle)} />}
>
<div
className={cx('ResizableBox', className)}
Expand Down

0 comments on commit fd2fa94

Please sign in to comment.