From c683b5e37b4685828ed342b8b7c06abfac7ac8fb Mon Sep 17 00:00:00 2001 From: cucadmuh <49571317+cucadmuh@users.noreply.github.com> Date: Wed, 3 Jun 2026 22:38:57 +0300 Subject: [PATCH] fix(cards): selection ring clipping on browse grids (WebKitGTK) (#962) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(artists): inset selection ring on grid cards, stop composer hover clip Artist multi-select used a positive outline-offset that clipped in the first grid row and sat outside the card border on hover. Match album cards with an inset ring; drop composer-card hover translateY that sheared the top edge in the in-page scrollport. Reported by zunoz (v1.47.0-rc.3). * fix(cards): selection ring via inset ::after overlay on WebKitGTK grids Replace outline-based multi-select rings on album/artist/playlist cards with the same inset ::after box-shadow pattern used for card focus rings (card.css) — avoids clipping and the 1px gap vs the inner border on overflow:hidden tiles in All Albums and related browse grids. * docs: note browse grid selection ring fix in CHANGELOG (PR #962) * docs(changelog): credit zunoz on Psysonic Discord for PR #962 --- CHANGELOG.md | 7 +++++++ src/components/artists/ArtistsGridView.tsx | 7 +------ src/components/playlists/PlaylistCard.tsx | 8 +------- src/styles/components/album-row-container.css | 19 ++++++++++++++++--- .../artist-card-selection-checkbox.css | 19 +++++++++++++++++++ .../composer-grid-text-only-compact.css | 1 - 6 files changed, 44 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b48d8a14..415f7174 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -436,6 +436,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Scoped search on Composers no longer replaces the Navidrome role-scoped catalog with generic artist index/search3 hits that merge split composer credits into one joined name and id — results stay split like the scroll overview. +### Browse grids — multi-select ring no longer clips (WebKitGTK) + +**By [@cucadmuh](https://github.com/cucadmuh), reported by zunoz on the Psysonic Discord, PR [#962](https://github.com/Psychotoxical/psysonic/pull/962)** + +* Multi-select rings on Artists, All Albums, Playlists, and related card grids use an inset `::after` overlay (same approach as card focus rings) instead of `outline` on `overflow: hidden` tiles — fixes top-row clipping and the ~1px gap vs the inner border on Wayland/WebKitGTK. + + ### In-page browse — virtual scroll and cover-art priority **By [@cucadmuh](https://github.com/cucadmuh), PR [#783](https://github.com/Psychotoxical/psysonic/pull/783)** diff --git a/src/components/artists/ArtistsGridView.tsx b/src/components/artists/ArtistsGridView.tsx index ca94185c..6358c75a 100644 --- a/src/components/artists/ArtistsGridView.tsx +++ b/src/components/artists/ArtistsGridView.tsx @@ -24,7 +24,7 @@ type TilePropsShared = Omit; function ArtistGridTile({ artist, ...rest }: TileProps) { return (
{ if (rest.selectionMode) { rest.toggleSelect(artist.id); @@ -40,11 +40,6 @@ function ArtistGridTile({ artist, ...rest }: TileProps) { rest.openContextMenu(e.clientX, e.clientY, artist, 'artist'); } }} - style={rest.selectionMode && rest.selectedIds.has(artist.id) ? { - outline: '2px solid var(--accent)', - outlineOffset: '2px', - borderRadius: 'var(--radius-md)', - } : {}} > {rest.selectionMode && (
diff --git a/src/components/playlists/PlaylistCard.tsx b/src/components/playlists/PlaylistCard.tsx index 65b2077d..a9b432d3 100644 --- a/src/components/playlists/PlaylistCard.tsx +++ b/src/components/playlists/PlaylistCard.tsx @@ -43,7 +43,7 @@ export default function PlaylistCard({ return (
{ if (selectionMode) { toggleSelect(pl.id, { shiftKey: e.shiftKey }); @@ -60,12 +60,6 @@ export default function PlaylistCard({ } }} onMouseLeave={() => { if (deleteConfirmId === pl.id) setDeleteConfirmId(null); }} - style={selectionMode && selectedIds.has(pl.id) ? { - position: 'relative', - outline: '2px solid var(--accent)', - outlineOffset: '2px', - borderRadius: 'var(--radius-md)' - } : { position: 'relative' }} > {!selectionMode && (
diff --git a/src/styles/components/album-row-container.css b/src/styles/components/album-row-container.css index 7fcb8a2b..aa3ff8d2 100644 --- a/src/styles/components/album-row-container.css +++ b/src/styles/components/album-row-container.css @@ -346,8 +346,21 @@ } .album-card--selected { - outline: 2px solid var(--accent); - outline-offset: -2px; + outline: none; +} + +/* Inset overlay ring — same approach as `.card:focus-visible::after` in card.css: + outline + overflow:hidden clips on WebKitGTK/Wayland; inset box-shadow on ::after + paints above the cover without growing the card box. */ +.album-card--selected::after, +.album-card.selected::after { + content: ''; + position: absolute; + inset: 0; + border-radius: inherit; + box-shadow: inset 0 0 0 2px var(--accent); + z-index: 4; + pointer-events: none; } .album-card-select-check { @@ -362,7 +375,7 @@ display: flex; align-items: center; justify-content: center; - z-index: 3; + z-index: 5; pointer-events: none; } diff --git a/src/styles/components/artist-card-selection-checkbox.css b/src/styles/components/artist-card-selection-checkbox.css index 6c7ebf73..8fe429d2 100644 --- a/src/styles/components/artist-card-selection-checkbox.css +++ b/src/styles/components/artist-card-selection-checkbox.css @@ -25,6 +25,25 @@ color: var(--ctp-crust); } +.artist-card--selectable { + cursor: pointer; +} + +/* Inset overlay ring — see `.album-card--selected::after` / `.card:focus-visible::after`. */ +.artist-card--selected { + outline: none; +} + +.artist-card--selected::after { + content: ''; + position: absolute; + inset: 0; + border-radius: inherit; + box-shadow: inset 0 0 0 2px var(--accent); + z-index: 4; + pointer-events: none; +} + /* ── Albums selection bar (portal) ── */ .albums-selection-bar { position: fixed; diff --git a/src/styles/components/composer-grid-text-only-compact.css b/src/styles/components/composer-grid-text-only-compact.css index d9e867d2..fa151d80 100644 --- a/src/styles/components/composer-grid-text-only-compact.css +++ b/src/styles/components/composer-grid-text-only-compact.css @@ -34,7 +34,6 @@ .composer-card:hover { border-color: var(--accent); background: var(--bg-hover); - transform: translateY(-1px); box-shadow: 0 4px 12px -6px rgba(0, 0, 0, 0.4); }