fix(sidebar): centre Playlists icon and unify hover hitbox in collapsed mode (#481)

* fix(sidebar): centre Playlists icon and unify hover hitbox in collapsed mode

The Playlists nav entry had its own special render path with a wrapper
div, header-row and `flex: 1` main link to fit the expand-toggle
button. Those elements remained active in collapsed mode too, where
`padding-right` on the header-row and `flex: 1` on the link made the
icon sit off-centre and gave the row a wider hover hitbox than every
other collapsed sidebar item.

Hoist the `isCollapsed` check above the playlists special-case so that
in collapsed mode Playlists renders through the same plain `<NavLink>`
branch as Artists / Albums / Favorites / etc. The expanded-mode
treatment (wrapper, header-row, expand-toggle, nested playlist list)
is unchanged.

* docs: changelog entry for PR #481

Logs the collapsed-sidebar Playlists icon centring fix in v1.46.0
"## Fixed".
This commit is contained in:
Frank Stellmacher
2026-05-06 16:12:50 +02:00
committed by GitHub
parent b084e96c1f
commit ebce53f8a7
2 changed files with 19 additions and 19 deletions
+6
View File
@@ -140,6 +140,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Limited loudness backfill warmup to the current track plus the next 5 tracks, reducing runaway analysis scheduling from large bulk queue updates.
* Added debug counters for prune results to make queue-pressure behavior visible during diagnostics.
### Sidebar — Playlists icon and hover hitbox in collapsed mode
**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#481](https://github.com/Psychotoxical/psysonic/pull/481)**
* The **Playlists** icon in the collapsed sidebar was **off-centre** and had a **wider hover background** than every other item, because it still rendered through the expanded-mode wrapper (with `padding-right` and a `flex: 1` main link to fit the expand-toggle). Collapsed mode now reuses the **standard nav-link path** — same hitbox, same alignment as Artists, Albums, Favorites, etc.
## [1.45.0] - 2026-05-04
## Added
+13 -19
View File
@@ -861,7 +861,7 @@ export default function Sidebar({
}
: {};
return item.to === '/playlists' ? (
return item.to === '/playlists' && !isCollapsed ? (
<div
key={item.to}
className={`sidebar-playlists-wrapper${rowClass ? ` ${rowClass}` : ''}`}
@@ -872,25 +872,21 @@ export default function Sidebar({
<NavLink
to={item.to}
className={({ isActive }) => `nav-link sidebar-playlists-main-link ${isActive ? 'active' : ''}`}
data-tooltip={isCollapsed ? t(item.labelKey) : undefined}
data-tooltip-pos="bottom"
>
<item.icon size={isCollapsed ? 22 : 18} />
{!isCollapsed && <span>{t(item.labelKey)}</span>}
<item.icon size={18} />
<span>{t(item.labelKey)}</span>
</NavLink>
{!isCollapsed && (
<button
className={`sidebar-playlists-toggle ${playlistsExpanded ? 'expanded' : ''}`}
onClick={() => setPlaylistsExpanded(!playlistsExpanded)}
aria-expanded={playlistsExpanded}
aria-label={playlistsExpanded ? t('sidebar.collapsePlaylists') : t('sidebar.expandPlaylists')}
data-tooltip={playlistsExpanded ? t('sidebar.collapsePlaylists') : t('sidebar.expandPlaylists')}
>
<ChevronRight size={14} />
</button>
)}
<button
className={`sidebar-playlists-toggle ${playlistsExpanded ? 'expanded' : ''}`}
onClick={() => setPlaylistsExpanded(!playlistsExpanded)}
aria-expanded={playlistsExpanded}
aria-label={playlistsExpanded ? t('sidebar.collapsePlaylists') : t('sidebar.expandPlaylists')}
data-tooltip={playlistsExpanded ? t('sidebar.collapsePlaylists') : t('sidebar.expandPlaylists')}
>
<ChevronRight size={14} />
</button>
</div>
{!isCollapsed && playlistsExpanded && (
{playlistsExpanded && (
<div className="sidebar-playlists-list">
{playlistsLoading ? (
<div className="sidebar-playlists-loading">
@@ -904,8 +900,6 @@ export default function Sidebar({
key={pl.id}
to={`/playlists/${pl.id}`}
className={({ isActive }) => `nav-link sidebar-playlist-item ${isActive ? 'active' : ''}`}
data-tooltip={isCollapsed ? displayPlaylistName(pl.name) : undefined}
data-tooltip-pos="bottom"
>
{isSmartPlaylistName(pl.name) ? <Sparkles size={12} /> : <PlayCircle size={12} />}
<span>{displayPlaylistName(pl.name)}</span>