fix: likers strip expands inline, no separate panel (#1303)
The prior PR moved liker avatars inline but left the hover tooltip
and mobile bottom sheet in place. On hover, a tooltip opened above
the track row and showed... the same avatars, just a few more of
them. That was redundant and, as you pointed out, the separate
panel opening on hover was the most egregious part.
New model: the inline strip *is* the interaction.
- hover → per-avatar lift (already worked via AvatarStack)
- click an avatar → navigate to /u/{handle}
- click "+N" → the stack itself expands in place to a
horizontally-scrollable strip of every liker. same widget, just
longer. lazy-fetched via the existing tooltip-cache so the
data is there the first time you expand and instant on
subsequent expansions
- click × (or click outside, or press Escape) → collapses back
No popover, no bottom sheet, no tooltip. One affordance, consistent
across mobile and desktop.
Implementation
- AvatarStack.svelte — new scrollable + maxScrollWidth props.
When scrollable, the container gets overflow-x: auto, scroll-snap,
and a thin scrollbar. Overlap is preserved so it stays visually
the same widget, not a different one.
- LikersStrip.svelte — new wrapper that owns the expansion state
and the lazy fetch. Parents pass trackId + likeCount + topLikers
and don't think about anything else.
- TrackItem, TrackCard, track/[id]/+page.svelte — all the
tooltip/sheet state, hover timers, click-to-open-sheet handlers,
cursor: help, tooltip-open z-index gymnastics — all gone.
Replaced with <LikersStrip>.
- Deleted: LikersTooltip.svelte, LikersSheet.svelte,
likers-sheet.svelte.ts. Removed mount from +layout.svelte.
tooltip-cache.svelte.ts stays — LikersStrip uses it for the
expansion fetch.
Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com>
authored by