Fix sidebar scroll into view

This commit is contained in:
Gregory Schier
2025-11-18 13:30:37 -08:00
parent 569e506f32
commit 6863decd8e
3 changed files with 19 additions and 12 deletions

View File

@@ -112,6 +112,15 @@ function Sidebar({ className }: { className?: string }) {
treeRef.current?.selectItem(payload.model.id, true); treeRef.current?.selectItem(payload.model.id, true);
}); });
useEffect(() => {
return jotaiStore.sub(activeIdAtom, () => {
const activeId = jotaiStore.get(activeIdAtom);
if (activeId) {
treeRef.current?.selectItem(activeId, true);
}
});
}, [focusActiveItem]);
useHotKey( useHotKey(
'sidebar.filter', 'sidebar.filter',
() => { () => {
@@ -489,7 +498,7 @@ function Sidebar({ className }: { className?: string }) {
<Dropdown <Dropdown
items={[ items={[
{ {
label: 'Select Open Request', label: 'Focus Active Request',
leftSlot: <Icon icon="crosshair" />, leftSlot: <Icon icon="crosshair" />,
onSelect: () => { onSelect: () => {
const activeId = jotaiStore.get(activeIdAtom); const activeId = jotaiStore.get(activeIdAtom);
@@ -508,7 +517,8 @@ function Sidebar({ className }: { className?: string }) {
} }
return n; return n;
}); });
treeRef.current?.selectItem(activeId, true); treeRef.current?.selectItem(activeId, false);
treeRef.current?.focus();
}, },
}, },
{ {

View File

@@ -130,7 +130,8 @@ function TreeInner<T extends { id: string }>(
if ($el == null) { if ($el == null) {
return false; return false;
} else { } else {
$el?.focus(); $el.focus();
$el.scrollIntoView({ block: 'nearest' });
return true; return true;
} }
}, []); }, []);

View File

@@ -10,7 +10,7 @@ import { jotaiStore } from '../../../lib/jotai';
import type { ContextMenuProps, DropdownItem } from '../Dropdown'; import type { ContextMenuProps, DropdownItem } from '../Dropdown';
import { ContextMenu } from '../Dropdown'; import { ContextMenu } from '../Dropdown';
import { Icon } from '../Icon'; import { Icon } from '../Icon';
import { collapsedFamily, isCollapsedFamily, isLastFocusedFamily, isSelectedFamily } from './atoms'; import { collapsedFamily, isCollapsedFamily, isLastFocusedFamily, isSelectedFamily, } from './atoms';
import type { TreeNode } from './common'; import type { TreeNode } from './common';
import { getNodeKey } from './common'; import { getNodeKey } from './common';
import type { TreeProps } from './Tree'; import type { TreeProps } from './Tree';
@@ -39,6 +39,7 @@ export interface TreeItemHandle {
isRenaming: boolean; isRenaming: boolean;
rect: () => DOMRect; rect: () => DOMRect;
focus: () => void; focus: () => void;
scrollIntoView: () => void;
} }
const HOVER_CLOSED_FOLDER_DELAY = 800; const HOVER_CLOSED_FOLDER_DELAY = 800;
@@ -81,6 +82,9 @@ function TreeItem_<T extends { id: string }>({
} }
return listItemRef.current.getBoundingClientRect(); return listItemRef.current.getBoundingClientRect();
}, },
scrollIntoView: () => {
listItemRef.current?.scrollIntoView({ block: 'nearest' });
}
}), }),
[editing, getEditOptions], [editing, getEditOptions],
); );
@@ -118,14 +122,6 @@ function TreeItem_<T extends { id: string }>({
y: number; y: number;
} | null>(null); } | null>(null);
useEffect(
() =>
jotaiStore.sub(isSelectedFamily({ treeId, itemId: node.item.id }), () => {
listItemRef.current?.scrollIntoView({ block: 'nearest' });
}),
[node.item.id, treeId],
);
const handleClick = useCallback( const handleClick = useCallback(
(e: MouseEvent<HTMLButtonElement>) => onClick?.(node.item, e), (e: MouseEvent<HTMLButtonElement>) => onClick?.(node.item, e),
[node, onClick], [node, onClick],