1
0
Fork 0

feat(locker): add hover tooltip to wardrobe slot hotspots

- Wrap each wardrobe slot button with shadcn Tooltip component
- Show slot name and current item name on hover
- Use smooth fade-in/zoom-in animation from shadcn tooltip
- Position tooltip to the right of each hotspot with 8px offset
This commit is contained in:
Jason Fraley 2026-08-02 18:52:45 -04:00
parent f2de832ea4
commit be8e537385

View file

@ -22,6 +22,7 @@ import {
} from "@/lib/locker"; } from "@/lib/locker";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { getAssetIcon } from "./LockerGrid"; import { getAssetIcon } from "./LockerGrid";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
function slotIcon(icon: WardrobeSlotIcon, filled: boolean) { function slotIcon(icon: WardrobeSlotIcon, filled: boolean) {
const cls = filled ? "size-3.5" : "size-3"; const cls = filled ? "size-3.5" : "size-3";
@ -91,23 +92,33 @@ export function Wardrobe({
const value = slots[layout.name]; const value = slots[layout.name];
const asset = resolveSlotAsset(value, items); const asset = resolveSlotAsset(value, items);
return ( return (
<button <Tooltip key={layout.name}>
key={layout.name} <TooltipTrigger asChild>
type="button" <button
title={asset ? `${layout.label}: ${asset.name}` : `${layout.label} (empty)`} type="button"
aria-label={`${layout.label} slot: ${asset ? asset.name : "empty"}`} aria-label={`${layout.label} slot: ${asset ? asset.name : "empty"}`}
onClick={() => onSlotClick(layout.name)} onClick={() => onSlotClick(layout.name)}
className={cn( className={cn(
"absolute flex items-center justify-center rounded-full border transition-colors", "absolute flex items-center justify-center rounded-full border transition-colors",
"-translate-x-1/2 -translate-y-1/2 cursor-pointer", "-translate-x-1/2 -translate-y-1/2 cursor-pointer",
asset asset
? "size-7 border-amber-400/70 bg-amber-500/25 text-amber-200 hover:bg-amber-500/40" ? "size-7 border-amber-400/70 bg-amber-500/25 text-amber-200 hover:bg-amber-500/40"
: "size-6 border-border bg-background/80 text-muted-foreground hover:border-primary hover:text-foreground", : "size-6 border-border bg-background/80 text-muted-foreground hover:border-primary hover:text-foreground",
)} )}
style={{ left: `${layout.x}%`, top: `${layout.y}%` }} style={{ left: `${layout.x}%`, top: `${layout.y}%` }}
> >
{asset ? getAssetIcon(asset.assetType, "size-3.5") : slotIcon(layout.icon, false)} {asset ? getAssetIcon(asset.assetType, "size-3.5") : slotIcon(layout.icon, false)}
</button> </button>
</TooltipTrigger>
<TooltipContent side="right" sideOffset={8}>
<div className="flex flex-col gap-0.5">
<span className="font-medium">{layout.label}</span>
<span className="text-muted-foreground">
{asset ? asset.name : "Empty"}
</span>
</div>
</TooltipContent>
</Tooltip>
); );
})} })}
</div> </div>