-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wrap antd tree to enable scrolling while dragging (#8162)
* Wrap antd tree to enable scrolling while dragging * add explanation to biome ignore comment * add changelog entry * fix typing * extract magic numbers into constants * apply feedback - send datasource id in correct format to backend - fix dataset renaming in dataset settings - fix typo in filename --------- Co-authored-by: Michael Büßemeyer <[email protected]>
- Loading branch information
1 parent
53cad36
commit e0fd7b6
Showing
10 changed files
with
93 additions
and
24 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
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
64 changes: 64 additions & 0 deletions
64
frontend/javascripts/oxalis/view/right-border-tabs/scrollable_virtualized_tree.tsx
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,64 @@ | ||
import { Tree as AntdTree, type TreeProps } from "antd"; | ||
import type { BasicDataNode } from "antd/es/tree"; | ||
import { throttle } from "lodash"; | ||
import { useCallback, useRef } from "react"; | ||
import type RcTree from "rc-tree"; | ||
|
||
const MIN_SCROLL_SPEED = 30; | ||
const MAX_SCROLL_SPEED = 200; | ||
const MIN_SCROLL_AREA_HEIGHT = 60; | ||
const SCROLL_AREA_RATIO = 10; // 1/10th of the container height | ||
const THROTTLE_TIME = 25; | ||
|
||
function ScrollableVirtualizedTree<T extends BasicDataNode>( | ||
props: TreeProps<T> & { ref: React.RefObject<RcTree> }, | ||
) { | ||
const wrapperRef = useRef<HTMLDivElement>(null); | ||
// biome-ignore lint/correctness/useExhaustiveDependencies: biome is not smart enough to notice that the function needs to be re-created when wrapperRef changes. | ||
const onDragOver = useCallback( | ||
throttle((info: { event: React.DragEvent<HTMLDivElement> }) => { | ||
const target = info.event.target as HTMLElement; | ||
if (!target || !wrapperRef.current) { | ||
return; | ||
} | ||
const { bottom: currentBottom, top: currentTop } = target.getBoundingClientRect(); | ||
const { bottom: boxBottom, top: boxTop } = wrapperRef.current.getBoundingClientRect(); | ||
const scrollableList = wrapperRef.current.getElementsByClassName("ant-tree-list-holder")[0]; | ||
if (!scrollableList) { | ||
return; | ||
} | ||
const scrollAreaHeight = Math.max( | ||
MIN_SCROLL_AREA_HEIGHT, | ||
Math.round((boxBottom - boxTop) / SCROLL_AREA_RATIO), | ||
); | ||
|
||
if (currentTop > boxBottom - scrollAreaHeight && scrollableList) { | ||
const ratioWithinScrollingArea = | ||
(currentTop - (boxBottom - scrollAreaHeight)) / scrollAreaHeight; | ||
const scrollingValue = Math.max( | ||
Math.round(ratioWithinScrollingArea * MAX_SCROLL_SPEED), | ||
MIN_SCROLL_SPEED, | ||
); | ||
scrollableList.scrollTop += scrollingValue; | ||
} | ||
if (boxTop + scrollAreaHeight > currentBottom && scrollableList) { | ||
const ratioWithinScrollingArea = | ||
(boxTop + scrollAreaHeight - currentBottom) / scrollAreaHeight; | ||
const scrollingValue = Math.max( | ||
Math.round(ratioWithinScrollingArea * MAX_SCROLL_SPEED), | ||
MIN_SCROLL_SPEED, | ||
); | ||
scrollableList.scrollTop -= scrollingValue; | ||
} | ||
}, THROTTLE_TIME), | ||
[wrapperRef], | ||
); | ||
|
||
return ( | ||
<div ref={wrapperRef}> | ||
<AntdTree {...props} onDragOver={onDragOver} /> | ||
</div> | ||
); | ||
} | ||
|
||
export default ScrollableVirtualizedTree; |
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
File renamed without changes.
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
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