refactor: redesign element transform manager interface (#11679)

### Change
- Rename `ElementTransformManager` -> `InteractivityManager`
- Now you can `event.on` and `action.onXXX` method to extend interactivity behaviour. The old approach of overriding methods directly is deprecated.
This commit is contained in:
doouding
2025-04-22 08:18:22 +00:00
parent e457e2f8a8
commit 52953ce8e3
22 changed files with 507 additions and 389 deletions

View File

@@ -5,12 +5,9 @@ import {
} from '@blocksuite/affine-model';
import {
type DragExtensionInitializeContext,
type ExtensionDragEndContext,
type ExtensionDragMoveContext,
type ExtensionDragStartContext,
getTopElements,
GfxExtensionIdentifier,
TransformExtension,
InteractivityExtension,
} from '@blocksuite/std/gfx';
import {
@@ -19,7 +16,7 @@ import {
isFrameBlock,
} from './frame-manager';
export class FrameHighlightManager extends TransformExtension {
export class FrameHighlightManager extends InteractivityExtension {
static override key = 'frame-highlight-manager';
get frameMgr() {
@@ -32,57 +29,54 @@ export class FrameHighlightManager extends TransformExtension {
return this.std.getOptional(OverlayIdentifier('frame')) as FrameOverlay;
}
override onDragInitialize(_: DragExtensionInitializeContext): {
onDragStart?: (context: ExtensionDragStartContext) => void;
onDragMove?: (context: ExtensionDragMoveContext) => void;
onDragEnd?: (context: ExtensionDragEndContext) => void;
clear?: () => void;
} {
if (!this.frameMgr || !this.frameHighlightOverlay) {
return {};
}
override mounted() {
this.action.onDragInitialize((_: DragExtensionInitializeContext) => {
if (!this.frameMgr || !this.frameHighlightOverlay) {
return {};
}
let hoveredFrame: FrameBlockModel | null = null;
const { frameMgr, frameHighlightOverlay } = this;
let draggedFrames: FrameBlockModel[] = [];
let hoveredFrame: FrameBlockModel | null = null;
const { frameMgr, frameHighlightOverlay } = this;
let draggedFrames: FrameBlockModel[] = [];
return {
onDragStart(context) {
draggedFrames = context.elements
.map(elem => elem.model)
.filter(model => isFrameBlock(model));
},
onDragMove(context) {
const { dragLastPos } = context;
return {
onDragStart(context) {
draggedFrames = context.elements
.map(elem => elem.model)
.filter(model => isFrameBlock(model));
},
onDragMove(context) {
const { dragLastPos } = context;
hoveredFrame = frameMgr.getFrameFromPoint(
[dragLastPos.x, dragLastPos.y],
draggedFrames
);
hoveredFrame = frameMgr.getFrameFromPoint(
[dragLastPos.x, dragLastPos.y],
draggedFrames
);
if (hoveredFrame && !hoveredFrame.isLocked()) {
frameHighlightOverlay.highlight(hoveredFrame);
} else {
frameHighlightOverlay.clear();
}
},
onDragEnd(context) {
const topElements = getTopElements(
context.elements.map(elem =>
elem.model.group instanceof MindmapElementModel
? elem.model.group
: elem.model
)
);
if (hoveredFrame) {
frameMgr.addElementsToFrame(hoveredFrame, topElements);
} else {
topElements.forEach(elem => frameMgr.removeFromParentFrame(elem));
}
if (hoveredFrame && !hoveredFrame.isLocked()) {
frameHighlightOverlay.highlight(hoveredFrame);
} else {
frameHighlightOverlay.clear();
}
},
onDragEnd(context) {
const topElements = getTopElements(
context.elements.map(elem =>
elem.model.group instanceof MindmapElementModel
? elem.model.group
: elem.model
)
);
if (hoveredFrame) {
frameMgr.addElementsToFrame(hoveredFrame, topElements);
} else {
topElements.forEach(elem => frameMgr.removeFromParentFrame(elem));
}
frameHighlightOverlay.clear();
},
};
},
};
});
}
}