feat: support snap when resizing element (#12563)

Fixes [BS-2753](https://linear.app/affine-design/issue/BS-2753/)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added snapping support when resizing elements, improving alignment and precision during resize operations.
  - Introduced new resize event handlers allowing extensions to customize resize behavior with start, move, and end callbacks.

- **Bug Fixes**
  - Improved handling of snapping state to prevent errors during drag and resize actions.

- **Tests**
  - Updated resizing tests to ensure consistent snapping behavior by removing default elements that could interfere with test results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
doouding
2025-05-28 02:47:01 +00:00
parent f5f959692a
commit cf456c888f
6 changed files with 253 additions and 34 deletions
@@ -13,6 +13,12 @@ import type {
ExtensionDragMoveContext,
ExtensionDragStartContext,
} from '../types/drag.js';
import type {
ExtensionElementResizeContext,
ExtensionElementResizeEndContext,
ExtensionElementResizeMoveContext,
ExtensionElementResizeStartContext,
} from '../types/resize.js';
import type { ExtensionElementSelectContext } from '../types/select.js';
export const InteractivityExtensionIdentifier =
@@ -100,7 +106,7 @@ export class InteractivityEventAPI {
}
}
type ActionContextMap = {
export type ActionContextMap = {
dragInitialize: {
context: DragExtensionInitializeContext;
returnType: {
@@ -119,6 +125,14 @@ type ActionContextMap = {
| undefined
>;
};
elementResize: {
context: ExtensionElementResizeContext;
returnType: {
onResizeStart?: (context: ExtensionElementResizeStartContext) => void;
onResizeMove?: (context: ExtensionElementResizeMoveContext) => void;
onResizeEnd?: (context: ExtensionElementResizeEndContext) => void;
};
};
elementSelect: {
context: ExtensionElementSelectContext;
returnType: void;
@@ -144,6 +158,18 @@ export class InteractivityActionAPI {
};
}
onElementResize(
handler: (
ctx: ActionContextMap['elementResize']['context']
) => ActionContextMap['elementResize']['returnType']
) {
this._handlers['elementResize'] = handler;
return () => {
return delete this._handlers['elementResize'];
};
}
onRequestElementsClone(
handler: (
ctx: ActionContextMap['elementsClone']['context']