feat(desktop): align tab preview popover animation with tooltip
- Skip the open delay when hovering a neighbouring tab within 300ms of a previous close, mirroring the tooltip's skipDelayDuration so sliding across tabs doesn't re-wait the full delay. - Add ignoreSafeArea so the non-interactive preview hides immediately on mouse-out (design: 0ms mouse-out delay). - Tighten the reduced-motion rule to also cover [data-closed], matching tooltip-v2.
This commit is contained in:
@@ -115,7 +115,8 @@
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
[data-component="session-tab-popover"] {
|
||||
[data-component="session-tab-popover"],
|
||||
[data-component="session-tab-popover"][data-closed] {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,11 @@ import "./titlebar-tab-popover.css"
|
||||
const OPEN_DELAY = 200
|
||||
// Mouse-out delay: hide instantly.
|
||||
const CLOSE_DELAY = 0
|
||||
// After a preview closes, hovering a neighbouring tab within this window skips
|
||||
// the open delay — mirrors the tooltip's skipDelayDuration so moving across
|
||||
// tabs doesn't re-wait the full delay each time.
|
||||
const SKIP_WINDOW = 300
|
||||
let lastClosedAt = 0
|
||||
|
||||
export interface TabPreviewData {
|
||||
projectName?: string
|
||||
@@ -24,12 +29,23 @@ export function TabPreviewPopover(props: {
|
||||
}) {
|
||||
let triggerEl: HTMLDivElement | undefined
|
||||
|
||||
// Kobalte reads openDelay lazily when the pointer enters the trigger, so this
|
||||
// resolves the skip window per-hover.
|
||||
const resolveOpenDelay = () => (Date.now() - lastClosedAt < SKIP_WINDOW ? 0 : OPEN_DELAY)
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
if (!open) lastClosedAt = Date.now()
|
||||
props.onOpenChange(open)
|
||||
}
|
||||
|
||||
return (
|
||||
<Kobalte
|
||||
open={props.open}
|
||||
onOpenChange={props.onOpenChange}
|
||||
openDelay={OPEN_DELAY}
|
||||
onOpenChange={handleOpenChange}
|
||||
openDelay={resolveOpenDelay()}
|
||||
closeDelay={CLOSE_DELAY}
|
||||
// The preview is non-interactive (pointer-events: none), so there is no
|
||||
// safe area to traverse — leaving the tab hides it immediately.
|
||||
ignoreSafeArea
|
||||
placement="bottom-start"
|
||||
gutter={6}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user