fix(desktop): show statusbar item tooltips on hover

Statusbar items declared a 'title' string (e.g. YOLO, gateway health,
agents, cron, version, context usage) that was populated by
use-statusbar-items.tsx but never forwarded to the rendered DOM in
StatusbarControls — so every statusbar button/menu/text/link had no
hover hint.

Wrap the four render branches (menu trigger, text, link, action) in
the existing 'Tip' component from components/ui/tooltip.tsx. Tip is
self-contained (carries its own Provider), instant (delayDuration=0),
themed (bg-foreground/text-background, auto-inverts per theme), and
already in use elsewhere in the desktop shell. Renders the child
untouched when label is falsy, so items without a title stay
zero-cost.
This commit is contained in:
David Metcalfe 2026-06-21 10:27:16 -07:00 committed by ethernet
parent 5de8a8fbe8
commit da73223f4a

View file

@ -2,6 +2,7 @@ import type { ComponentProps, ReactNode } from 'react'
import { useNavigate } from 'react-router-dom'
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
import { Tip } from '@/components/ui/tooltip'
import { cn } from '@/lib/utils'
// Shared chrome styling for interactive statusbar items (button / link / menu
@ -97,93 +98,101 @@ function StatusbarItemView({ item, navigate }: { item: StatusbarItem; navigate:
if (item.variant === 'menu' && (item.menuContent || (item.menuItems && item.menuItems.length > 0))) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className={cn(STATUSBAR_ACTION_CLASS, item.className)} disabled={item.disabled} type="button">
{content}
</button>
</DropdownMenuTrigger>
<DropdownMenuContent
align={item.menuAlign ?? 'start'}
className={cn('w-56', item.menuContent && 'p-0', item.menuClassName)}
side="top"
sideOffset={8}
>
{item.menuContent
? item.menuContent
: (item.menuItems ?? [])
.filter(menuItem => !menuItem.hidden)
.map(menuItem => (
<DropdownMenuItem
className={cn('gap-2 text-foreground focus:bg-accent [&_svg]:size-4', menuItem.className)}
disabled={menuItem.disabled}
key={menuItem.id}
onSelect={() => {
if (menuItem.to) {
navigate(menuItem.to)
}
<Tip label={item.title}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className={cn(STATUSBAR_ACTION_CLASS, item.className)} disabled={item.disabled} type="button">
{content}
</button>
</DropdownMenuTrigger>
<DropdownMenuContent
align={item.menuAlign ?? 'start'}
className={cn('w-56', item.menuContent && 'p-0', item.menuClassName)}
side="top"
sideOffset={8}
>
{item.menuContent
? item.menuContent
: (item.menuItems ?? [])
.filter(menuItem => !menuItem.hidden)
.map(menuItem => (
<DropdownMenuItem
className={cn('gap-2 text-foreground focus:bg-accent [&_svg]:size-4', menuItem.className)}
disabled={menuItem.disabled}
key={menuItem.id}
onSelect={() => {
if (menuItem.to) {
navigate(menuItem.to)
}
menuItem.onSelect?.()
}}
>
{menuItem.href ? (
<a
className="inline-flex w-full items-center gap-2"
href={menuItem.href}
rel="noreferrer"
target="_blank"
>
{menuItem.icon}
<span className="truncate">{menuItem.label}</span>
</a>
) : (
<>
{menuItem.icon}
<span className="truncate">{menuItem.label}</span>
</>
)}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
menuItem.onSelect?.()
}}
>
{menuItem.href ? (
<a
className="inline-flex w-full items-center gap-2"
href={menuItem.href}
rel="noreferrer"
target="_blank"
>
{menuItem.icon}
<span className="truncate">{menuItem.label}</span>
</a>
) : (
<>
{menuItem.icon}
<span className="truncate">{menuItem.label}</span>
</>
)}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</Tip>
)
}
if (item.variant === 'text' && !item.onSelect && !item.to && !item.href) {
return (
<div
className={cn(
'inline-flex h-full items-center gap-1 px-1.5 text-[0.6875rem] text-(--ui-text-tertiary)',
item.className
)}
>
{content}
</div>
<Tip label={item.title}>
<div
className={cn(
'inline-flex h-full items-center gap-1 px-1.5 text-[0.6875rem] text-(--ui-text-tertiary)',
item.className
)}
>
{content}
</div>
</Tip>
)
}
if (item.href || item.variant === 'link') {
return (
<a className={cn(STATUSBAR_ACTION_CLASS, item.className)} href={item.href} rel="noreferrer" target="_blank">
{content}
</a>
<Tip label={item.title}>
<a className={cn(STATUSBAR_ACTION_CLASS, item.className)} href={item.href} rel="noreferrer" target="_blank">
{content}
</a>
</Tip>
)
}
return (
<button
className={cn(STATUSBAR_ACTION_CLASS, item.className)}
disabled={item.disabled}
onClick={event => {
if (item.to) {
navigate(item.to)
}
<Tip label={item.title}>
<button
className={cn(STATUSBAR_ACTION_CLASS, item.className)}
disabled={item.disabled}
onClick={event => {
if (item.to) {
navigate(item.to)
}
item.onSelect?.({ shiftKey: event.shiftKey })
}}
type="button"
>
{content}
</button>
item.onSelect?.({ shiftKey: event.shiftKey })
}}
type="button"
>
{content}
</button>
</Tip>
)
}