feat(editor): table block supports drag-and-drop sorting (#10065)

close: BS-2477
This commit is contained in:
zzj3720
2025-02-10 14:14:53 +00:00
parent 964f2e1bfd
commit c78d6b81c6
15 changed files with 496 additions and 49 deletions

View File

@@ -1,4 +1,5 @@
type OffsetList = number[];
import type { OffsetList } from './types';
type CellOffsets = {
rows: OffsetList;
columns: OffsetList;

View File

@@ -0,0 +1,3 @@
export * from './cell-select';
export * from './linear-move';
export * from './types';

View File

@@ -0,0 +1,38 @@
import type { OffsetList } from './types';
export const getTargetIndexByDraggingOffset = (
offsets: OffsetList,
draggingIndex: number,
indicatorLeft: number
) => {
const originalStart = offsets[draggingIndex];
const originalWidth = offsets[draggingIndex + 1] - originalStart;
const indicatorRight = indicatorLeft + originalWidth;
const isForward = indicatorLeft > originalStart;
const startIndex = isForward ? draggingIndex + 1 : 0;
const endIndex = isForward ? offsets.length - 1 : draggingIndex - 1;
if (isForward) {
for (let i = endIndex; i >= startIndex; i--) {
const blockCenter = (offsets[i] + offsets[i + 1]) / 2;
if (indicatorRight > blockCenter) {
return {
targetIndex: i,
isForward,
};
}
}
} else {
for (let i = startIndex; i <= endIndex; i++) {
const blockCenter = (offsets[i] + offsets[i + 1]) / 2;
if (indicatorLeft < blockCenter) {
return {
targetIndex: i,
isForward,
};
}
}
}
return {
targetIndex: undefined,
isForward,
};
};

View File

@@ -0,0 +1 @@
export type OffsetList = number[];

View File

@@ -1,5 +1,9 @@
import { generateKeyBetween } from 'fractional-indexing';
function hasSamePrefix(a: string, b: string) {
return a.startsWith(b) || b.startsWith(a);
}
/**
* generate a key between a and b, the result key is always satisfied with a < result < b.
* the key always has a random suffix, so there is no need to worry about collision.
@@ -59,7 +63,7 @@ export function generateFractionalIndexingKeyBetween(
return generateKeyBetween(aSubkey, null) + '0' + postfix();
} else if (aSubkey !== null && bSubkey !== null) {
// generate a key between a and b
if (aSubkey === bSubkey && a !== null && b !== null) {
if (hasSamePrefix(aSubkey, bSubkey) && a !== null && b !== null) {
// conflict, if the subkeys are the same, generate a key between fullkeys
return generateKeyBetween(a, b) + '0' + postfix();
} else {

View File

@@ -1,9 +1,9 @@
export * from './auto-scroll';
export * from './button-popper';
export * from './cell-select';
export * from './collapsed';
export * from './dnd';
export * from './dom';
export * from './drag-helper';
export * from './edgeless';
export * from './event';
export * from './file';