From 00fbf6ac13d1680f5ba3ea8087529473843f57b7 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 19 Aug 2026 11:50:57 +0100 Subject: [PATCH 1/5] fix(webapp): align tree mouse and keyboard interactions --- .../route.tsx | 22 +++++++++---- .../app/routes/storybook.tree-view/route.tsx | 32 ++++++++++++------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index 53ba28b800b..f318a7e5a85 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -968,6 +968,14 @@ function TasksTreeView({ }, }); + const getInteractiveNodeProps = useCallback( + (id: string) => ({ + ...getNodeProps(id), + onClick: () => selectNode(id), + }), + [getNodeProps, selectNode] + ); + return (
@@ -1047,7 +1055,7 @@ function TasksTreeView({ autoFocus tree={events} nodes={nodes} - getNodeProps={getNodeProps} + getNodeProps={getInteractiveNodeProps} getTreeProps={getTreeProps} parentClassName="pl-3" renderNode={({ node, state, index }) => ( @@ -1058,9 +1066,6 @@ function TasksTreeView({ ? "bg-grid-dimmed hover:bg-grid-bright" : "bg-transparent hover:bg-grid-dimmed" )} - onClick={() => { - selectNode(node.id); - }} >
{Array.from({ length: node.level }).map((_, index) => ( @@ -1070,9 +1075,12 @@ function TasksTreeView({ isSelected={state.selected} /> ))} -
{ @@ -1098,7 +1106,7 @@ function TasksTreeView({ ) : (
)} -
+
diff --git a/apps/webapp/app/routes/storybook.tree-view/route.tsx b/apps/webapp/app/routes/storybook.tree-view/route.tsx index ac58d71b185..a78d7ccd4c5 100644 --- a/apps/webapp/app/routes/storybook.tree-view/route.tsx +++ b/apps/webapp/app/routes/storybook.tree-view/route.tsx @@ -4,7 +4,7 @@ import { FolderOpenIcon, MagnifyingGlassIcon, } from "@heroicons/react/20/solid"; -import { useRef, useState } from "react"; +import { useCallback, useRef, useState } from "react"; import { Button } from "~/components/primitives/Buttons"; import { Input } from "~/components/primitives/Input"; import type { Tree } from "~/components/primitives/TreeView/TreeView"; @@ -177,6 +177,14 @@ function TreeViewParent({ }, }); + const getInteractiveNodeProps = useCallback( + (id: string) => ({ + ...getNodeProps(id), + onClick: () => toggleNodeSelection(id), + }), + [getNodeProps, toggleNodeSelection] + ); + return (
@@ -203,7 +211,7 @@ function TreeViewParent({ autoFocus tree={tree} nodes={nodes} - getNodeProps={getNodeProps} + getNodeProps={getInteractiveNodeProps} getTreeProps={getTreeProps} parentClassName="h-96 bg-background-deep" renderNode={({ node, state, index, virtualizer, virtualItem }) => ( @@ -215,20 +223,22 @@ function TreeViewParent({ "flex cursor-pointer items-center gap-2 py-1 hover:bg-blue-500/10", state.selected && "bg-blue-500/20 hover:bg-blue-500/30" )} - onClick={() => { - toggleNodeSelection(node.id); - }} > -
{ e.stopPropagation(); toggleExpandNode(node.id); selectNode(node.id, true); }} - onKeyDown={(e) => { - console.log(e.key); - }} > {node.hasChildren ? ( state.expanded ? ( @@ -239,7 +249,7 @@ function TreeViewParent({ ) : ( )} -
+
{node.data.title}
)} From f8cdd56f6db993ddd7e1aa795fb764b99ad8dbbb Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 19 Aug 2026 13:00:15 +0100 Subject: [PATCH 2/5] fix(webapp): preserve tree keyboard focus --- .../route.tsx | 13 ++++++------- .../app/routes/storybook.tree-view/route.tsx | 15 +++++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index f318a7e5a85..9b8a81f7508 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -968,13 +968,10 @@ function TasksTreeView({ }, }); - const getInteractiveNodeProps = useCallback( - (id: string) => ({ - ...getNodeProps(id), - onClick: () => selectNode(id), - }), - [getNodeProps, selectNode] - ); + const getInteractiveNodeProps = (id: string) => ({ + ...getNodeProps(id), + onClick: () => selectNode(id), + }); return (
@@ -1077,6 +1074,7 @@ function TasksTreeView({ ))}