-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: remove legacy drag handle logic (#9246)
- Loading branch information
1 parent
a187f23
commit 23dcaa9
Showing
14 changed files
with
237 additions
and
718 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
161 changes: 161 additions & 0 deletions
161
blocksuite/affine/shared/src/utils/dnd/get-drop-rect-by-point.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import { BLOCK_ID_ATTR } from '@blocksuite/block-std'; | ||
import type { Point } from '@blocksuite/global/utils'; | ||
import type { BlockModel } from '@blocksuite/store'; | ||
|
||
import { getRectByBlockComponent } from '../dom/index.js'; | ||
import { matchFlavours } from '../model/index.js'; | ||
import { DropFlags } from './types.js'; | ||
|
||
const ATTR_SELECTOR = `[${BLOCK_ID_ATTR}]`; | ||
|
||
/** | ||
* Gets the drop rect by block and point. | ||
*/ | ||
export function getDropRectByPoint( | ||
point: Point, | ||
model: BlockModel, | ||
element: Element | ||
): null | { | ||
rect: DOMRect; | ||
flag: DropFlags; | ||
} { | ||
const result = { | ||
rect: getRectByBlockComponent(element), | ||
flag: DropFlags.Normal, | ||
}; | ||
|
||
const isDatabase = matchFlavours(model, [ | ||
'affine:database' as BlockSuite.Flavour, | ||
]); | ||
|
||
if (isDatabase) { | ||
const table = getDatabaseBlockTableElement(element); | ||
if (!table) { | ||
return result; | ||
} | ||
|
||
let bounds = table.getBoundingClientRect(); | ||
if (model.isEmpty.value) { | ||
result.flag = DropFlags.EmptyDatabase; | ||
|
||
if (point.y < bounds.top) return result; | ||
|
||
const header = getDatabaseBlockColumnHeaderElement(element); | ||
if (!header) { | ||
return null; | ||
} | ||
|
||
bounds = header.getBoundingClientRect(); | ||
result.rect = new DOMRect( | ||
result.rect.left, | ||
bounds.bottom, | ||
result.rect.width, | ||
1 | ||
); | ||
|
||
return result; | ||
} | ||
|
||
result.flag = DropFlags.Database; | ||
const rows = getDatabaseBlockRowsElement(element); | ||
if (!rows) { | ||
return null; | ||
} | ||
const rowsBounds = rows.getBoundingClientRect(); | ||
|
||
if (point.y < rowsBounds.top || point.y > rowsBounds.bottom) return result; | ||
|
||
const elements = document.elementsFromPoint(point.x, point.y); | ||
const len = elements.length; | ||
let e; | ||
let i = 0; | ||
for (; i < len; i++) { | ||
e = elements[i]; | ||
|
||
if (e.classList.contains('affine-database-block-row-cell-content')) { | ||
const cellRect = getCellRect(e, bounds); | ||
if (!cellRect) { | ||
return null; | ||
} | ||
result.rect = cellRect; | ||
return result; | ||
} | ||
|
||
if (e.classList.contains('affine-database-block-row')) { | ||
e = e.querySelector(ATTR_SELECTOR); | ||
if (!e) { | ||
return null; | ||
} | ||
const cellRect = getCellRect(e, bounds); | ||
if (!cellRect) { | ||
return null; | ||
} | ||
result.rect = cellRect; | ||
return result; | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
const parent = element.parentElement; | ||
if (parent?.classList.contains('affine-database-block-row-cell-content')) { | ||
result.flag = DropFlags.Database; | ||
const cellRect = getCellRect(parent); | ||
if (!cellRect) { | ||
return null; | ||
} | ||
result.rect = cellRect; | ||
return result; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
/** | ||
* Gets the table of the database. | ||
*/ | ||
function getDatabaseBlockTableElement(element: Element) { | ||
return element.querySelector('.affine-database-block-table'); | ||
} | ||
|
||
/** | ||
* Gets the column header of the database. | ||
*/ | ||
function getDatabaseBlockColumnHeaderElement(element: Element) { | ||
return element.querySelector('.affine-database-column-header'); | ||
} | ||
|
||
/** | ||
* Gets the rows of the database. | ||
*/ | ||
function getDatabaseBlockRowsElement(element: Element) { | ||
return element.querySelector('.affine-database-block-rows'); | ||
} | ||
|
||
function getCellRect(element: Element, bounds?: DOMRect) { | ||
if (!bounds) { | ||
const table = element.closest('.affine-database-block-table'); | ||
if (!table) { | ||
return null; | ||
} | ||
bounds = table.getBoundingClientRect(); | ||
} | ||
// affine-database-block-row-cell | ||
const col = element.parentElement; | ||
if (!col) { | ||
return null; | ||
} | ||
// affine-database-block-row | ||
const row = col.parentElement; | ||
if (!row) { | ||
return null; | ||
} | ||
const colRect = col.getBoundingClientRect(); | ||
return new DOMRect( | ||
bounds.left, | ||
colRect.top, | ||
colRect.right - bounds.left, | ||
colRect.height | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
export * from './calc-drop-target.js'; | ||
export * from './get-drop-rect-by-point.js'; | ||
export * from './legacy.js'; | ||
export type { DropResult } from './types.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import type { BlockComponent } from '@blocksuite/block-std'; | ||
import type { Rect } from '@blocksuite/global/utils'; | ||
import type { BlockModel } from '@blocksuite/store'; | ||
|
||
export interface EditingState { | ||
element: BlockComponent; | ||
model: BlockModel; | ||
rect: DOMRect; | ||
} | ||
|
||
/** | ||
* Returns a flag for the drop target. | ||
*/ | ||
export enum DropFlags { | ||
Normal, | ||
Database, | ||
EmptyDatabase, | ||
} | ||
|
||
/** | ||
* A dropping type. | ||
*/ | ||
export type DroppingType = 'none' | 'before' | 'after' | 'database'; | ||
|
||
export type DropResult = { | ||
type: DroppingType; | ||
rect: Rect; | ||
modelState: EditingState; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.