mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-23 13:29:02 +08:00
feat(editor): table block supports drag-and-drop sorting (#10065)
close: BS-2477
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import type { OffsetList } from './types';
|
||||
|
||||
type CellOffsets = {
|
||||
rows: OffsetList;
|
||||
columns: OffsetList;
|
||||
};
|
||||
export const domToOffsets = (
|
||||
element: HTMLElement,
|
||||
rowSelector: string,
|
||||
cellSelector: string
|
||||
): CellOffsets | undefined => {
|
||||
const rowDoms = Array.from(element.querySelectorAll(rowSelector));
|
||||
const firstRowDom = rowDoms[0];
|
||||
if (!firstRowDom) return;
|
||||
const columnDoms = Array.from(firstRowDom.querySelectorAll(cellSelector));
|
||||
const rows: OffsetList = [];
|
||||
const columns: OffsetList = [];
|
||||
for (let i = 0; i < rowDoms.length; i++) {
|
||||
const rect = rowDoms[i].getBoundingClientRect();
|
||||
if (!rect) continue;
|
||||
if (i === 0) {
|
||||
rows.push(rect.top);
|
||||
}
|
||||
rows.push(rect.bottom);
|
||||
}
|
||||
for (let i = 0; i < columnDoms.length; i++) {
|
||||
const rect = columnDoms[i].getBoundingClientRect();
|
||||
if (!rect) continue;
|
||||
if (i === 0) {
|
||||
columns.push(rect.left);
|
||||
}
|
||||
columns.push(rect.right);
|
||||
}
|
||||
|
||||
return {
|
||||
rows,
|
||||
columns,
|
||||
};
|
||||
};
|
||||
|
||||
export const getIndexByPosition = (
|
||||
positions: OffsetList,
|
||||
offset: number,
|
||||
reverse = false
|
||||
) => {
|
||||
if (reverse) {
|
||||
return positions.slice(1).findIndex(p => offset <= p);
|
||||
}
|
||||
return positions.slice(0, -1).findLastIndex(p => offset >= p);
|
||||
};
|
||||
|
||||
export const getRangeByPositions = (
|
||||
positions: OffsetList,
|
||||
start: number,
|
||||
end: number
|
||||
) => {
|
||||
const startIndex = getIndexByPosition(positions, start, true);
|
||||
const endIndex = getIndexByPosition(positions, end);
|
||||
return {
|
||||
start: startIndex,
|
||||
end: endIndex,
|
||||
};
|
||||
};
|
||||
|
||||
export const getAreaByOffsets = (
|
||||
offsets: CellOffsets,
|
||||
top: number,
|
||||
bottom: number,
|
||||
left: number,
|
||||
right: number
|
||||
) => {
|
||||
const { rows, columns } = offsets;
|
||||
const startRow = getIndexByPosition(rows, top, true);
|
||||
const endRow = getIndexByPosition(rows, bottom);
|
||||
const startColumn = getIndexByPosition(columns, left, true);
|
||||
const endColumn = getIndexByPosition(columns, right);
|
||||
return {
|
||||
top: startRow,
|
||||
bottom: endRow,
|
||||
left: startColumn,
|
||||
right: endColumn,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './cell-select';
|
||||
export * from './linear-move';
|
||||
export * from './types';
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export type OffsetList = number[];
|
||||
Reference in New Issue
Block a user