test-web / test (push) Failing after 33s
First wave of Home visual polish (UI tasks 78/79/81/85): - CardActionCluster like/queue/menu cluster is now opacity-0 and fades in on group-hover or focus-within. The group class moves from the inner anchor to the outer card wrapper so the cluster (positioned outside the anchor) participates in the same hover scope. PlaylistCard refresh kebab gets the same treatment. - AlbumCard drops the year line. Title plus artist is enough on Home tiles; the album detail page still shows the year. - HorizontalScrollRow h2 picks up a flex-baseline layout with a trailing 12-wide accent rule (after:bg-accent/60), so section headers read as chapter breaks instead of identical plain text. - AlbumCard art-wrap is shadow-sm by default and lifts to shadow-lg plus ring-accent/40 on hover. Pairs with the existing group-hover:scale-1.03 for a clean lift-on-mouseover feel.
68 lines
2.4 KiB
Svelte
68 lines
2.4 KiB
Svelte
<script lang="ts">
|
|
import type { Snippet } from 'svelte';
|
|
import { Plus } from 'lucide-svelte';
|
|
import LikeButton from './LikeButton.svelte';
|
|
|
|
// Shared chrome for AlbumCard / ArtistCard / CompactTrackCard. Owns
|
|
// the top-right Like + add-to-queue cluster and the bottom-right
|
|
// menu slot — the bits that were drifting between the three cards
|
|
// (focus-ring, play-overlay-adjacent positioning, button styling).
|
|
//
|
|
// Per-card data fetching + onPlay/onAdd logic stays in the calling
|
|
// component; the wrapping element (a vs button) and art container
|
|
// also stay there since their differences are load-bearing.
|
|
//
|
|
// stopPropagation is applied to both wrapper divs so clicks on the
|
|
// action elements never bubble to the parent — works for both
|
|
// <a>-wrapped cards (AlbumCard/ArtistCard) and <button>-wrapped
|
|
// ones (CompactTrackCard).
|
|
|
|
let {
|
|
likeEntityType,
|
|
likeEntityId,
|
|
onAdd,
|
|
addLabel,
|
|
addDisabled = false,
|
|
menu
|
|
}: {
|
|
likeEntityType: 'track' | 'album' | 'artist';
|
|
likeEntityId: string;
|
|
onAdd: (e: MouseEvent) => void;
|
|
addLabel: string;
|
|
addDisabled?: boolean;
|
|
menu: Snippet;
|
|
} = $props();
|
|
</script>
|
|
|
|
<!-- Like + Add to queue + Menu cluster. Hover-revealed so the
|
|
default tile state is just the cover artwork — controls fade in
|
|
when the user hovers the card or focuses any of the buttons
|
|
(focus-within keeps it visible during keyboard navigation). -->
|
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
<div
|
|
class="absolute right-2 top-2 z-10 flex gap-1 opacity-0 transition-opacity duration-150
|
|
group-hover:opacity-100 focus-within:opacity-100"
|
|
onclick={(e) => e.stopPropagation()}
|
|
>
|
|
<LikeButton entityType={likeEntityType} entityId={likeEntityId} />
|
|
<button
|
|
type="button"
|
|
aria-label={addLabel}
|
|
onclick={onAdd}
|
|
disabled={addDisabled}
|
|
class="rounded-full bg-surface px-2 py-1 text-sm text-text-secondary hover:text-text-primary focus-visible:ring-2 focus-visible:ring-accent disabled:opacity-50"
|
|
>
|
|
<Plus size={16} strokeWidth={1} />
|
|
</button>
|
|
</div>
|
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
<div
|
|
class="absolute right-2 bottom-2 z-10 opacity-0 transition-opacity duration-150
|
|
group-hover:opacity-100 focus-within:opacity-100"
|
|
onclick={(e) => e.stopPropagation()}
|
|
>
|
|
{@render menu()}
|
|
</div>
|