fix(bases): axis-aware kanban auto-scroll overflow matches reference example

This commit is contained in:
Philipinho
2026-05-27 23:40:02 +01:00
parent 48ff82800b
commit 6935a73e4f
3 changed files with 22 additions and 13 deletions
@@ -71,7 +71,7 @@ export function BaseKanban({
source.data.type === "base-kanban-column", source.data.type === "base-kanban-column",
[], [],
); );
useKanbanAutoScroll(boardRef, canScrollBoard); useKanbanAutoScroll(boardRef, "horizontal", canScrollBoard);
useEffect(() => { useEffect(() => {
if (!hasNextPage || isFetchingNextPage) return; if (!hasNextPage || isFetchingNextPage) return;
@@ -40,7 +40,7 @@ export function KanbanColumn({
source.data.type === "base-kanban-card", source.data.type === "base-kanban-card",
[], [],
); );
useKanbanAutoScroll(bodyRef, canScrollColumn); useKanbanAutoScroll(bodyRef, "vertical", canScrollColumn);
return ( return (
<div className={classes.column} data-column-key={column.key}> <div className={classes.column} data-column-key={column.key}>
@@ -7,18 +7,32 @@ type CanScrollArgs = {
source: { data: Record<string, unknown> }; source: { data: Record<string, unknown> };
}; };
// How far past each edge the cursor can roam and still drive scroll. const OVERFLOW_PX = 6000;
// 120px gives users a generous "drag past the column" affordance before
// scrolling stops — matches what other kanbans (Linear, Notion) do. type Axis = "horizontal" | "vertical";
const OVERFLOW_PX = 120;
export function useKanbanAutoScroll( export function useKanbanAutoScroll(
ref: RefObject<HTMLElement | null>, ref: RefObject<HTMLElement | null>,
axis: Axis,
canScroll: (args: CanScrollArgs) => boolean = () => true, canScroll: (args: CanScrollArgs) => boolean = () => true,
) { ) {
useEffect(() => { useEffect(() => {
const el = ref.current; const el = ref.current;
if (!el) return; if (!el) return;
const overflow =
axis === "vertical"
? {
forTopEdge: { top: OVERFLOW_PX, right: 0, left: 0 },
forBottomEdge: { bottom: OVERFLOW_PX, right: 0, left: 0 },
forLeftEdge: { left: 0, top: 0, bottom: 0 },
forRightEdge: { right: 0, top: 0, bottom: 0 },
}
: {
forTopEdge: { top: 0, right: 0, left: 0 },
forBottomEdge: { bottom: 0, right: 0, left: 0 },
forLeftEdge: { left: OVERFLOW_PX, top: 0, bottom: 0 },
forRightEdge: { right: OVERFLOW_PX, top: 0, bottom: 0 },
};
return combine( return combine(
autoScrollForElements({ autoScrollForElements({
element: el, element: el,
@@ -29,13 +43,8 @@ export function useKanbanAutoScroll(
element: el, element: el,
canScroll, canScroll,
getConfiguration: () => ({ maxScrollSpeed: "fast" }), getConfiguration: () => ({ maxScrollSpeed: "fast" }),
getOverflow: () => ({ getOverflow: () => overflow,
forTopEdge: { top: OVERFLOW_PX },
forBottomEdge: { bottom: OVERFLOW_PX },
forLeftEdge: { left: OVERFLOW_PX },
forRightEdge: { right: OVERFLOW_PX },
}),
}), }),
); );
}, [ref, canScroll]); }, [ref, axis, canScroll]);
} }