Skip to content

Commit 116dec2

Browse files
committed
feat: add scrollable
1 parent 47876b6 commit 116dec2

File tree

6 files changed

+69
-50
lines changed

6 files changed

+69
-50
lines changed

blocksuite/affine/shared/src/utils/event.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export function requestConnectedFrame(
170170
* A wrapper around `requestConnectedFrame` that only calls at most once in one frame
171171
*/
172172
export function requestThrottledConnectedFrame<
173-
T extends (...args: unknown[]) => void,
173+
T extends (...args: any[]) => void,
174174
>(func: T, element?: HTMLElement): T {
175175
let raqId: number | undefined = undefined;
176176
let latestArgs: unknown[] = [];

blocksuite/affine/widget-drag-handle/src/watchers/drag-event-watcher.ts

+26-49
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ import {
1414
TelemetryProvider,
1515
} from '@blocksuite/affine-shared/services';
1616
import {
17-
autoScroll,
1817
captureEventTarget,
1918
type DropResult,
2019
getBlockComponentsExcludeSubtrees,
2120
getRectByBlockComponent,
2221
getScrollContainer,
2322
matchFlavours,
23+
requestThrottledConnectedFrame,
2424
SpecProvider,
2525
} from '@blocksuite/affine-shared/utils';
2626
import {
@@ -61,10 +61,6 @@ export type DragBlockPayload = DragPayload<DragBlockEntity, DragFromBlockSuite>;
6161
export class DragEventWatcher {
6262
dropIndicator: null | DropIndicator = null;
6363

64-
lastDragPoint: Point | null = null;
65-
66-
rafID: number = 0;
67-
6864
get host() {
6965
return this.widget.host;
7066
}
@@ -122,23 +118,22 @@ export class DragEventWatcher {
122118

123119
private readonly _cleanup = () => {
124120
this._clearDropIndicator();
125-
this.clearRaf();
126121
this.widget.hide(true);
127122
this.std.selection.setGroup('gfx', []);
128123
};
129124

130-
private readonly _onDragMove = (
131-
point: Point,
132-
payload: DragBlockPayload,
133-
dropPayload: DropPayload,
134-
block: BlockComponent
135-
) => {
136-
this._createDropIndicator();
137-
this.clearRaf();
138-
this.rafID = requestAnimationFrame(() => {
139-
this._updateDropIndicator(point, payload, dropPayload, block, true);
140-
});
141-
};
125+
private readonly _onDragMove = requestThrottledConnectedFrame(
126+
(
127+
point: Point,
128+
payload: DragBlockPayload,
129+
dropPayload: DropPayload,
130+
block: BlockComponent
131+
) => {
132+
this._createDropIndicator();
133+
this._updateDropIndicator(point, payload, dropPayload, block);
134+
},
135+
this.widget
136+
);
142137

143138
/**
144139
* When dragging, should update indicator position and target drop block id
@@ -220,8 +215,7 @@ export class DragEventWatcher {
220215
point: Point,
221216
dragPayload: DragBlockPayload,
222217
dropPayload: DropPayload,
223-
dropBlock: BlockComponent,
224-
shouldAutoScroll: boolean = false
218+
dropBlock: BlockComponent
225219
) => {
226220
const closestNoteBlock = dropBlock && getParentNoteBlock(dropBlock);
227221

@@ -245,37 +239,8 @@ export class DragEventWatcher {
245239
}
246240

247241
this.lastDragPoint = point;
248-
249-
if (this.mode === 'page') {
250-
if (!shouldAutoScroll) return;
251-
252-
const scrollContainer = getScrollContainer(this.widget.rootComponent);
253-
const result = autoScroll(scrollContainer, point.y);
254-
if (!result) {
255-
this.clearRaf();
256-
return;
257-
}
258-
this.rafID = requestAnimationFrame(() =>
259-
this._updateDropIndicator(
260-
point,
261-
dragPayload,
262-
dropPayload,
263-
dropBlock,
264-
true
265-
)
266-
);
267-
} else {
268-
this.clearRaf();
269-
}
270242
};
271243

272-
clearRaf() {
273-
if (this.rafID) {
274-
cancelAnimationFrame(this.rafID);
275-
this.rafID = 0;
276-
}
277-
}
278-
279244
private readonly _resetDropResult = () => {
280245
if (this.dropIndicator) this.dropIndicator.rect = null;
281246
};
@@ -670,6 +635,7 @@ export class DragEventWatcher {
670635
const widget = this.widget;
671636
const std = this.std;
672637
const disposables = widget.disposables;
638+
const scrollable = getScrollContainer(this.host);
673639

674640
disposables.add(
675641
std.dnd.draggable<DragBlockEntity>({
@@ -718,6 +684,17 @@ export class DragEventWatcher {
718684
})
719685
);
720686

687+
if (scrollable) {
688+
disposables.add(
689+
std.dnd.autoScroll<DragBlockEntity>({
690+
element: scrollable,
691+
canScroll: ({ source }) => {
692+
return source.data.draggable?.entity?.type === 'blocks';
693+
},
694+
})
695+
);
696+
}
697+
721698
// used to handle drag move and drop
722699
disposables.add(
723700
std.dnd.monitor<DragBlockEntity>({

blocksuite/framework/block-std/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"license": "MIT",
1616
"dependencies": {
1717
"@atlaskit/pragmatic-drag-and-drop": "^1.4.0",
18+
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.0",
1819
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
1920
"@blocksuite/global": "workspace:*",
2021
"@blocksuite/inline": "workspace:*",

blocksuite/framework/block-std/src/extension/dnd.ts

+25
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import { disableNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview';
88
import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
99
import type { DropTargetRecord } from '@atlaskit/pragmatic-drag-and-drop/types';
10+
import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
1011
import {
1112
attachClosestEdge,
1213
type Edge,
@@ -22,6 +23,7 @@ import type {
2223
ElementDropEventMap,
2324
ElementDropTargetFeedbackArgs,
2425
ElementMonitorFeedbackArgs,
26+
OriginalAutoScrollOption,
2527
OriginalDraggableOption,
2628
OriginalDropTargetOption,
2729
OriginalMonitorOption,
@@ -173,6 +175,22 @@ export type MonitorOption<
173175
) => boolean;
174176
} & ElementDragEventMap<DragPayload<PayloadEntity, PayloadFrom>, DropPayload>;
175177

178+
export type AutoScroll<
179+
PayloadEntity extends DragEntity,
180+
PayloadFrom extends DragFrom,
181+
> = {
182+
element: HTMLElement;
183+
canScroll?: (
184+
args: ElementDragEventBaseArgs<DragPayload<PayloadEntity, PayloadFrom>>
185+
) => void;
186+
getAllowedAxis?: (
187+
args: ElementDragEventBaseArgs<DragPayload<PayloadEntity, PayloadFrom>>
188+
) => ReturnType<Required<OriginalAutoScrollOption>['getAllowedAxis']>;
189+
getConfiguration?: (
190+
args: ElementDragEventBaseArgs<DragPayload<PayloadEntity, PayloadFrom>>
191+
) => ReturnType<Required<OriginalAutoScrollOption>['getConfiguration']>;
192+
};
193+
176194
export const DndExtensionIdentifier = LifeCycleWatcherIdentifier(
177195
'DndController'
178196
) as ServiceIdentifier<DndController>;
@@ -289,4 +307,11 @@ export class DndController extends LifeCycleWatcher {
289307
>(args: MonitorOption<PayloadEntity, PayloadFrom, DropPayload<DropData>>) {
290308
return monitorForElements(args as OriginalMonitorOption);
291309
}
310+
311+
autoScroll<
312+
PayloadEntity extends DragEntity = DragEntity,
313+
PayloadFrom extends DragFrom = DragFromBlockSuite,
314+
>(options: AutoScroll<PayloadEntity, PayloadFrom>) {
315+
return autoScrollForElements(options as OriginalAutoScrollOption);
316+
}
292317
}

blocksuite/framework/block-std/src/extension/dnd/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
DropTargetRecord,
1313
ElementDragType,
1414
} from '@atlaskit/pragmatic-drag-and-drop/types';
15+
import type { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
1516

1617
export type ElementDragEventBaseArgs<Payload, DropPayload = {}> = {
1718
/**
@@ -111,3 +112,7 @@ export type OriginalDropTargetOption = Parameters<
111112
>[0];
112113

113114
export type OriginalMonitorOption = Parameters<typeof monitorForElements>[0];
115+
116+
export type OriginalAutoScrollOption = Parameters<
117+
typeof autoScrollForElements
118+
>[0];

yarn.lock

+11
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,16 @@ __metadata:
12101210
languageName: node
12111211
linkType: hard
12121212

1213+
"@atlaskit/pragmatic-drag-and-drop-auto-scroll@npm:^2.1.0":
1214+
version: 2.1.0
1215+
resolution: "@atlaskit/pragmatic-drag-and-drop-auto-scroll@npm:2.1.0"
1216+
dependencies:
1217+
"@atlaskit/pragmatic-drag-and-drop": "npm:^1.4.0"
1218+
"@babel/runtime": "npm:^7.0.0"
1219+
checksum: 10/a137947d240b01414c8235d9b3a5c949456ef3877488abdbfa92c491631ade10dd7fd6b3dc5ca31077617067c44dd1e90b1f6d1049b71d05d7064db92bc7810b
1220+
languageName: node
1221+
linkType: hard
1222+
12131223
"@atlaskit/pragmatic-drag-and-drop-hitbox@npm:^1.0.3":
12141224
version: 1.0.3
12151225
resolution: "@atlaskit/pragmatic-drag-and-drop-hitbox@npm:1.0.3"
@@ -3813,6 +3823,7 @@ __metadata:
38133823
resolution: "@blocksuite/block-std@workspace:blocksuite/framework/block-std"
38143824
dependencies:
38153825
"@atlaskit/pragmatic-drag-and-drop": "npm:^1.4.0"
3826+
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "npm:^2.1.0"
38163827
"@atlaskit/pragmatic-drag-and-drop-hitbox": "npm:^1.0.3"
38173828
"@blocksuite/global": "workspace:*"
38183829
"@blocksuite/inline": "workspace:*"

0 commit comments

Comments
 (0)