Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Patch Changes

- Clicking between nodes no longer triggers phantom selection.

## 0.17.1

### Patch Changes
Expand Down
39 changes: 36 additions & 3 deletions src/components/tree-view/TreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export const TreeView = <T,>({
width={width}
paddingTop={10}
paddingBottom={10}
rowHeight={35}
rowHeight={50}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it is just for dev purpose, no?

disableDrag={disableDrag}
disableDrop={({ parentNode, dragNodes, index }) => {
if (canDrop) {
Expand Down Expand Up @@ -327,7 +327,8 @@ const Row = <T,>({ children, ...props }: RowProps<T>) => {
const target = e.target as HTMLElement | null;
if (target) {
const isInActionsToolbar = target.closest(".actions");
const interactiveSelector = 'button, a[href], input, textarea, select, [role="menuitem"], [role="button"]';
const interactiveSelector =
'button, a[href], input, textarea, select, [role="menuitem"], [role="button"]';
const isInteractive = target.closest(interactiveSelector);
if (isInActionsToolbar || isInteractive) {
return;
Expand All @@ -346,6 +347,37 @@ const Row = <T,>({ children, ...props }: RowProps<T>) => {
}
};

// Block everything if clicking outside the actual row content (between items).
const handleRowMouseEvent = (e: React.MouseEvent<HTMLElement>) => {
const target = e.target as HTMLElement;
const rowContent = e.currentTarget.querySelector(
".c__tree-view--row-content"
);

// Allow toolbar/interactives (menus, links, inputs…)
const interactiveSelector =
'button, a[href], input, textarea, select, [role="menuitem"], [role="button"]';
const inToolbar = target.closest(".actions");
const isInteractive = target.closest(interactiveSelector);

// Only allow primary click (leave context-menu/drag)
const isPrimaryClick = "button" in e && e.button === 0;
if (!isPrimaryClick) return;

const inside = !!rowContent && rowContent.contains(target);
const outside = !inside && !inToolbar && !isInteractive;

if (outside) {
e.preventDefault();
e.stopPropagation();
return;
}

if (e.type === "click") {
props.node.handleClick(e);
}
};

if (isTitle || isSeparator) {
return (
<div
Expand All @@ -368,7 +400,8 @@ const Row = <T,>({ children, ...props }: RowProps<T>) => {
key={props.node.id}
ref={props.innerRef}
onFocus={(e) => e.stopPropagation()}
onClick={props.node.handleClick}
onMouseDown={handleRowMouseEvent}
onClick={handleRowMouseEvent}
onKeyDown={handleKeyDown}
Comment on lines +403 to 405
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find handleRowMouseEvent does not solve the root problem, it is more a patch.

The root problem seems to have the children that is not the same height as the parent, on Docs c__tree-view--row is 35px, when the child is --docs-sub-page-item 30px, could we have the child that inherit from the parent height instead, and add a margin in c__tree-view--row to keep the space between rows ?
If we do that I have the feeling we will not need to add this pathc, wdyt ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or rowHeight could be a prop as well, to fit the app need.

>
<div className="c__tree-view--row-content">{children}</div>
Expand Down