дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
fix(ui): reorder dragged tabs live with a placeholder; drop terminal tabs on a group to join or split (#1054)
Dragging a tab showed no floating copy: the ghost cloned the tab's classes, and .tab { position: relative } loaded after .ghost { position: fixed }. The ghost is now positioned inline, and a tab dragged within its strip stays as an empty slot the other tabs move around; the insertion line for tabs from another strip is drawn inside the edge tabs so the scroller doesn't clip it. A terminal group is now a drop target like an editor pane: the middle joins the group, an edge splits off a new group (dropZoneAt moves to ui and is shared).
Closes #1052
Co-authored-by: fuqiuluo <[email protected]>
Цей коміт міститься в:
1 джерело
e20eb1acf8
коміт
2b20c0f38e
11 files changed
+423
-55
No files matched your search
@@ -64,6 +64,29 @@ export function isOutsideWindow(
|
||||
return x < rect.left || x >= rect.right || y < rect.top || y >= rect.bottom;
|
||||
}
|
||||
|
||||
export type DropEdge = "left" | "right" | "top" | "bottom";
|
||||
|
||||
/**
|
||||
* Where a drop at (`x`, `y`) over `rect` lands: the nearest edge when within its
|
||||
* outer quarter (a tab dropped there splits off a new pane), else the middle.
|
||||
*/
|
||||
export function dropZoneAt(
|
||||
x: number,
|
||||
y: number,
|
||||
rect: { left: number; top: number; width: number; height: number },
|
||||
): DropEdge | "center" {
|
||||
const fx = (x - rect.left) / Math.max(1, rect.width);
|
||||
const fy = (y - rect.top) / Math.max(1, rect.height);
|
||||
const edges: Array<[DropEdge, number]> = [
|
||||
["left", fx],
|
||||
["right", 1 - fx],
|
||||
["top", fy],
|
||||
["bottom", 1 - fy],
|
||||
];
|
||||
const [edge, dist] = edges.reduce((a, b) => (b[1] < a[1] ? b : a));
|
||||
return dist < 0.25 ? edge : "center";
|
||||
}
|
||||
|
||||
export function dragSession(data: DragData): DragSession {
|
||||
let current: DropTarget | null = null;
|
||||
const enter = (t: DropTarget | null) => {
|
||||
@@ -131,6 +154,8 @@ export function startPointerDrag(
|
||||
ghost.classList.add(styles.ghost!);
|
||||
ghost.setAttribute("aria-hidden", "true");
|
||||
Object.assign(ghost.style, {
|
||||
// Inline: the copied classes (a tab's `position: relative`) can load after `.ghost`.
|
||||
position: "fixed",
|
||||
left: `${r.left}px`,
|
||||
top: `${r.top}px`,
|
||||
width: `${r.width}px`,
|
||||
|
||||
Reference in new issue
Заблокувати користувача