Resize handle improvements (#299)

Adds a delay to the resize handle line first showing so it doesn't flicker when the mouse briefly passes over it. Also removes an unnecessary findNode call that was happening on every move. Also adjusts the pointer offset based on the display container bounding rect.
This commit is contained in:
Evan Simkowitz 2024-08-30 12:31:03 -07:00 committed by GitHub
parent e488862355
commit e9b78c354f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 21 deletions

View File

@ -48,8 +48,11 @@ import { getCenter, navigateDirectionToOffset, setTransform } from "./utils";
interface ResizeContext {
handleId: string;
pixelToSizeRatio: number;
displayContainerRect?: Dimensions;
resizeHandleStartPx: number;
beforeNodeId: string;
beforeNodeStartSize: number;
afterNodeId: string;
afterNodeStartSize: number;
}
@ -929,18 +932,22 @@ export class LayoutModel {
*/
onResizeMove(resizeHandle: ResizeHandleProps, x: number, y: number) {
const parentIsRow = resizeHandle.flexDirection === FlexDirection.Row;
const parentNode = findNode(this.treeState.rootNode, resizeHandle.parentNodeId);
const beforeNode = parentNode.children![resizeHandle.parentIndex];
const afterNode = parentNode.children![resizeHandle.parentIndex + 1];
// If the resize context is out of date, update it and save it for future events.
if (this.resizeContext?.handleId !== resizeHandle.id) {
const parentNode = findNode(this.treeState.rootNode, resizeHandle.parentNodeId);
const beforeNode = parentNode.children![resizeHandle.parentIndex];
const afterNode = parentNode.children![resizeHandle.parentIndex + 1];
const addlProps = this.getter(this.additionalProps);
const pixelToSizeRatio = addlProps[resizeHandle.parentNodeId]?.pixelToSizeRatio;
if (beforeNode && afterNode && pixelToSizeRatio) {
this.resizeContext = {
handleId: resizeHandle.id,
displayContainerRect: this.displayContainerRef.current?.getBoundingClientRect(),
resizeHandleStartPx: resizeHandle.centerPx,
beforeNodeId: beforeNode.id,
afterNodeId: afterNode.id,
beforeNodeStartSize: beforeNode.size,
afterNodeStartSize: afterNode.size,
pixelToSizeRatio,
@ -953,7 +960,9 @@ export class LayoutModel {
}
}
const clientPoint = parentIsRow ? x : y;
const clientPoint = parentIsRow
? x - this.resizeContext.displayContainerRect?.left
: y - this.resizeContext.displayContainerRect?.top;
const clientDiff = (this.resizeContext.resizeHandleStartPx - clientPoint) * this.resizeContext.pixelToSizeRatio;
const minNodeSize = MinNodeSizePx * this.resizeContext.pixelToSizeRatio;
const beforeNodeSize = this.resizeContext.beforeNodeStartSize - clientDiff;
@ -968,11 +977,11 @@ export class LayoutModel {
type: LayoutTreeActionType.ResizeNode,
resizeOperations: [
{
nodeId: beforeNode.id,
nodeId: this.resizeContext.beforeNodeId,
size: beforeNodeSize,
},
{
nodeId: afterNode.id,
nodeId: this.resizeContext.afterNodeId,
size: afterNodeSize,
},
],

View File

@ -41,27 +41,29 @@
.resize-handle {
z-index: var(--zindex-layout-resize-handle);
.line {
visibility: hidden;
}
&.flex-row {
cursor: ew-resize;
.line {
height: 100%;
margin-left: calc(var(--gap-size-px) - 1px);
border-left: 2px solid var(--accent-color);
}
}
&.flex-column {
cursor: ns-resize;
.line {
margin-top: calc(var(--gap-size-px) - 1px);
}
}
&:hover {
&.flex-row .line {
border-left: 2px solid var(--accent-color);
}
&.flex-column .line {
border-bottom: 2px solid var(--accent-color);
}
}
&:hover .line {
visibility: visible;
transition: visibility calc(var(--animation-time-s) * 2) var(--animation-time-s);
}
}
.tile-node {
@ -133,13 +135,9 @@
.prefers-reduced-motion {
.tile-layout {
&.animate {
.tile-node,
.placeholder {
transition-duration: none;
transition-timing-function: none;
transition-property: none;
}
}
transition-duration: none !important;
transition-timing-function: none !important;
transition-property: none !important;
transition-delay: none !important;
}
}