mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Canvas: Fix inconsistent element resizing UX (#49450)
This commit is contained in:
parent
a92f85a87b
commit
5eb20739c2
@ -55,7 +55,7 @@ export const constraintViewable = (scene: Scene) => ({
|
||||
let verticalConstraintVisualization = null;
|
||||
let horizontalConstraintVisualization = null;
|
||||
|
||||
const constraint = targetElement?.options.constraint ?? {};
|
||||
const constraint = targetElement?.tempConstraint ?? targetElement?.options.constraint ?? {};
|
||||
|
||||
const borderStyle = '1px dashed #4af';
|
||||
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
import { notFoundItem } from 'app/features/canvas/elements/notFound';
|
||||
import { DimensionContext } from 'app/features/dimensions';
|
||||
|
||||
import { HorizontalConstraint, Placement, VerticalConstraint } from '../types';
|
||||
import { Constraint, HorizontalConstraint, Placement, VerticalConstraint } from '../types';
|
||||
|
||||
import { FrameState } from './frame';
|
||||
import { RootElement } from './root';
|
||||
@ -29,6 +29,9 @@ export class ElementState implements LayerElement {
|
||||
// Determine whether or not element is in motion or not (via moveable)
|
||||
isMoving = false;
|
||||
|
||||
// Temp stored constraint for visualization purposes (switch to top / left constraint to simplify some functionality)
|
||||
tempConstraint: Constraint | undefined;
|
||||
|
||||
// Filled in by ref
|
||||
div?: HTMLDivElement;
|
||||
|
||||
@ -377,68 +380,32 @@ export class ElementState implements LayerElement {
|
||||
// kinda like:
|
||||
// https://github.com/grafana/grafana-edge-app/blob/main/src/panels/draw/WrapItem.tsx#L44
|
||||
applyResize = (event: OnResize) => {
|
||||
const { options } = this;
|
||||
const { placement, constraint } = options;
|
||||
const { vertical, horizontal } = constraint ?? {};
|
||||
|
||||
const top = vertical === VerticalConstraint.Top || vertical === VerticalConstraint.TopBottom;
|
||||
const bottom = vertical === VerticalConstraint.Bottom || vertical === VerticalConstraint.TopBottom;
|
||||
const left = horizontal === HorizontalConstraint.Left || horizontal === HorizontalConstraint.LeftRight;
|
||||
const right = horizontal === HorizontalConstraint.Right || horizontal === HorizontalConstraint.LeftRight;
|
||||
const placement = this.options.placement!;
|
||||
|
||||
const style = event.target.style;
|
||||
const deltaX = event.delta[0];
|
||||
const deltaY = event.delta[1];
|
||||
const dirLR = event.direction[0];
|
||||
const dirTB = event.direction[1];
|
||||
|
||||
if (dirLR === 1) {
|
||||
// RIGHT
|
||||
if (right) {
|
||||
placement!.right! -= deltaX;
|
||||
style.right = `${placement!.right}px`;
|
||||
if (!left) {
|
||||
placement!.width = event.width;
|
||||
style.width = `${placement!.width}px`;
|
||||
}
|
||||
} else {
|
||||
placement!.width! = event.width;
|
||||
style.width = `${placement!.width}px`;
|
||||
}
|
||||
placement.width = event.width;
|
||||
style.width = `${placement.width}px`;
|
||||
} else if (dirLR === -1) {
|
||||
// LEFT
|
||||
if (left) {
|
||||
placement!.left! -= deltaX;
|
||||
placement!.width! = event.width;
|
||||
style.left = `${placement!.left}px`;
|
||||
style.width = `${placement!.width}px`;
|
||||
} else {
|
||||
placement!.width! += deltaX;
|
||||
style.width = `${placement!.width}px`;
|
||||
}
|
||||
placement.left! -= deltaX;
|
||||
placement.width = event.width;
|
||||
style.left = `${placement.left}px`;
|
||||
style.width = `${placement.width}px`;
|
||||
}
|
||||
|
||||
if (dirTB === -1) {
|
||||
// TOP
|
||||
if (top) {
|
||||
placement!.top! -= deltaY;
|
||||
placement!.height = event.height;
|
||||
style.top = `${placement!.top}px`;
|
||||
style.height = `${placement!.height}px`;
|
||||
} else {
|
||||
placement!.height = event.height;
|
||||
style.height = `${placement!.height}px`;
|
||||
}
|
||||
placement.top! -= deltaY;
|
||||
placement.height = event.height;
|
||||
style.top = `${placement.top}px`;
|
||||
style.height = `${placement.height}px`;
|
||||
} else if (dirTB === 1) {
|
||||
// BOTTOM
|
||||
if (bottom) {
|
||||
placement!.bottom! -= deltaY;
|
||||
placement!.height! = event.height;
|
||||
style.bottom = `${placement!.bottom}px`;
|
||||
style.height = `${placement!.height}px`;
|
||||
} else {
|
||||
placement!.height! = event.height;
|
||||
style.height = `${placement!.height}px`;
|
||||
}
|
||||
placement.height = event.height;
|
||||
style.height = `${placement.height}px`;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,7 @@ import {
|
||||
import { CanvasContextMenu } from 'app/plugins/panel/canvas/CanvasContextMenu';
|
||||
import { LayerActionID } from 'app/plugins/panel/canvas/types';
|
||||
|
||||
import { Placement } from '../types';
|
||||
import { HorizontalConstraint, Placement, VerticalConstraint } from '../types';
|
||||
|
||||
import { constraintViewable, dimensionViewable } from './ables';
|
||||
import { ElementState } from './element';
|
||||
@ -349,6 +349,18 @@ export class Scene {
|
||||
|
||||
this.moved.next(Date.now());
|
||||
})
|
||||
.on('resizeStart', (event) => {
|
||||
const targetedElement = this.findElementByTarget(event.target);
|
||||
|
||||
if (targetedElement) {
|
||||
targetedElement.tempConstraint = { ...targetedElement.options.constraint };
|
||||
targetedElement.options.constraint = {
|
||||
vertical: VerticalConstraint.Top,
|
||||
horizontal: HorizontalConstraint.Left,
|
||||
};
|
||||
targetedElement.setPlacementFromConstraint();
|
||||
}
|
||||
})
|
||||
.on('resize', (event) => {
|
||||
const targetedElement = this.findElementByTarget(event.target);
|
||||
targetedElement!.applyResize(event);
|
||||
@ -365,7 +377,12 @@ export class Scene {
|
||||
const targetedElement = this.findElementByTarget(event.target);
|
||||
|
||||
if (targetedElement) {
|
||||
targetedElement?.setPlacementFromConstraint();
|
||||
if (targetedElement.tempConstraint) {
|
||||
targetedElement.options.constraint = targetedElement.tempConstraint;
|
||||
targetedElement.tempConstraint = undefined;
|
||||
}
|
||||
|
||||
targetedElement.setPlacementFromConstraint();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -80,6 +80,8 @@ export const PlacementEditor: FC<StandardEditorProps<any, CanvasEditorOptions, P
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const constraint = element.tempConstraint ?? layout ?? {};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<QuickPositioning onPositionChange={onPositionChange} settings={settings} element={element} />
|
||||
@ -89,15 +91,11 @@ export const PlacementEditor: FC<StandardEditorProps<any, CanvasEditorOptions, P
|
||||
<ConstraintSelectionBox
|
||||
onVerticalConstraintChange={onVerticalConstraintChange}
|
||||
onHorizontalConstraintChange={onHorizontalConstraintChange}
|
||||
currentConstraints={element.options.constraint ?? {}}
|
||||
currentConstraints={constraint}
|
||||
/>
|
||||
<VerticalGroup>
|
||||
<Select options={verticalOptions} onChange={onVerticalConstraintSelect} value={layout?.vertical} />
|
||||
<Select
|
||||
options={horizontalOptions}
|
||||
onChange={onHorizontalConstraintSelect}
|
||||
value={options.constraint?.horizontal}
|
||||
/>
|
||||
<Select options={verticalOptions} onChange={onVerticalConstraintSelect} value={constraint.vertical} />
|
||||
<Select options={horizontalOptions} onChange={onHorizontalConstraintSelect} value={constraint.horizontal} />
|
||||
</VerticalGroup>
|
||||
</HorizontalGroup>
|
||||
</Field>
|
||||
|
Loading…
Reference in New Issue
Block a user