Skip to content

Commit 0a7dfc0

Browse files
authored
fix(app): lift up project hover state to layout (#18732)
1 parent 4c27e7f commit 0a7dfc0

2 files changed

Lines changed: 12 additions & 21 deletions

File tree

packages/app/src/pages/layout.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,6 +1989,10 @@ export default function Layout(props: ParentProps) {
19891989
onProjectMouseEnter: (worktree, event) => aim.enter(worktree, event),
19901990
onProjectMouseLeave: (worktree) => aim.leave(worktree),
19911991
onProjectFocus: (worktree) => aim.activate(worktree),
1992+
onHoverOpenChanged: (worktree, hoverOpen) => {
1993+
if (!hoverOpen && state.hoverProject && state.hoverProject !== worktree) return
1994+
setState("hoverProject", hoverOpen ? worktree : undefined)
1995+
},
19921996
navigateToProject,
19931997
openSidebar: () => layout.sidebar.open(),
19941998
closeProject,

packages/app/src/pages/layout/sidebar-project.tsx

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export type ProjectSidebarContext = {
2323
onProjectMouseEnter: (worktree: string, event: MouseEvent) => void
2424
onProjectMouseLeave: (worktree: string) => void
2525
onProjectFocus: (worktree: string) => void
26+
onHoverOpenChanged: (worktree: string, hovered: boolean) => void
2627
navigateToProject: (directory: string) => void
2728
openSidebar: () => void
2829
closeProject: (directory: string) => void
@@ -197,7 +198,6 @@ const ProjectPreviewPanel = (props: {
197198
projectChildren: Accessor<Map<string, string[]>>
198199
workspaceSessions: (directory: string) => ReturnType<typeof sortedRootSessions>
199200
workspaceChildren: (directory: string) => Map<string, string[]>
200-
setOpen: (value: boolean) => void
201201
ctx: ProjectSidebarContext
202202
language: ReturnType<typeof useLanguage>
203203
}): JSX.Element => (
@@ -264,7 +264,7 @@ const ProjectPreviewPanel = (props: {
264264
class="flex w-full text-left justify-start text-text-base px-2 hover:bg-transparent active:bg-transparent"
265265
onClick={() => {
266266
props.ctx.openSidebar()
267-
props.setOpen(false)
267+
props.ctx.onHoverOpenChanged(props.project.worktree, false)
268268
if (props.selected()) return
269269
props.ctx.navigateToProject(props.project.worktree)
270270
}}
@@ -289,28 +289,16 @@ export const SortableProject = (props: {
289289
const workspaceEnabled = createMemo(() => props.ctx.workspacesEnabled(props.project))
290290
const dirs = createMemo(() => props.ctx.workspaceIds(props.project))
291291
const [state, setState] = createStore({
292-
open: false,
293292
menu: false,
294293
suppressHover: false,
295294
})
296295

296+
const isHoverProject = () => props.ctx.hoverProject() === props.project.worktree
297297
const preview = createMemo(() => !props.mobile && props.ctx.sidebarOpened())
298298
const overlay = createMemo(() => !props.mobile && !props.ctx.sidebarOpened())
299-
const active = createMemo(
300-
() => state.menu || (preview() ? state.open : overlay() && props.ctx.hoverProject() === props.project.worktree),
301-
)
299+
const active = createMemo(() => state.menu || (preview() ? isHoverProject() : overlay() && isHoverProject()))
302300

303-
createEffect(() => {
304-
if (preview()) return
305-
if (!state.open) return
306-
setState("open", false)
307-
})
308-
309-
createEffect(() => {
310-
if (!selected()) return
311-
if (!state.open) return
312-
setState("open", false)
313-
})
301+
const hoverOpen = () => isHoverProject() && preview() && !selected() && !state.menu
314302

315303
const label = (directory: string) => {
316304
const [data] = globalSync.child(directory, { bootstrap: false })
@@ -351,7 +339,7 @@ export const SortableProject = (props: {
351339
workspacesEnabled={props.ctx.workspacesEnabled}
352340
closeProject={props.ctx.closeProject}
353341
setMenu={(value) => setState("menu", value)}
354-
setOpen={(value) => setState("open", value)}
342+
setOpen={(value) => props.ctx.onHoverOpenChanged(props.project.worktree, value)}
355343
setSuppressHover={(value) => setState("suppressHover", value)}
356344
language={language}
357345
/>
@@ -362,7 +350,7 @@ export const SortableProject = (props: {
362350
<div use:sortable classList={{ "opacity-30": sortable.isActiveDraggable }}>
363351
<Show when={preview() && !selected()} fallback={tile()}>
364352
<HoverCard
365-
open={!state.suppressHover && state.open && !state.menu}
353+
open={!state.suppressHover && hoverOpen() && !state.menu}
366354
openDelay={0}
367355
closeDelay={0}
368356
placement="right-start"
@@ -371,7 +359,7 @@ export const SortableProject = (props: {
371359
onOpenChange={(value) => {
372360
if (state.menu) return
373361
if (value && state.suppressHover) return
374-
setState("open", value)
362+
props.ctx.onHoverOpenChanged(props.project.worktree, value)
375363
if (value) props.ctx.setHoverSession(undefined)
376364
}}
377365
>
@@ -386,7 +374,6 @@ export const SortableProject = (props: {
386374
projectChildren={projectChildren}
387375
workspaceSessions={workspaceSessions}
388376
workspaceChildren={workspaceChildren}
389-
setOpen={(value) => setState("open", value)}
390377
ctx={props.ctx}
391378
language={language}
392379
/>

0 commit comments

Comments
 (0)