fix: align sidebar counts in a single right column
The previous count-alignment fix used invisible group-hover:visible for
hover-only buttons, but invisible still reserves layout space. Folder
rows had a permanent kebab slot that non-folder rows didn't, and active
heap rows had a Target indicator before the count — both shifted their
counts left of the rest. The result was visually misaligned counts.
- LeftSidebar folder kebab + HeapsPanel kebab/set-active: switch to
hidden group-hover:block so the slot occupies zero width in the
resting state. Counts now sit at the same right edge across folder,
non-folder, and heap rows.
- HeapsPanel: drop the standalone Target indicator from active heap
rows. Active state is signaled by the bold name (font-semibold)
already, and removing the indicator lets the heap count column line
up with everything else.
- Both kebab wrappers also use hidden group-hover:block on the wrapper
div so the menu trigger truly takes 0 width when not hovered.
On hover the kebab appears to the right of the count and pushes it
slightly left, as the user requested ("on hover we can push them to
make space for the burger").
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -338,17 +338,13 @@ export function HeapsPanel() {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Right-aligned cluster. Active indicator + count are
|
{/* Right cluster. Count is the rightmost element in the
|
||||||
* always visible; set-active and kebab appear on hover
|
* resting state — set-active and kebab use display:none
|
||||||
* to the RIGHT of the count, displacing it slightly so
|
* (not invisible) so they reserve no width until hover,
|
||||||
* the count column lines up with the rest of the
|
* keeping the count column aligned with the rest of the
|
||||||
* sidebar in the resting state. */}
|
* sidebar. The active heap is signaled by font-semibold
|
||||||
{isActive && (
|
* on the name above; the standalone Target indicator
|
||||||
<Target
|
* was making heap counts sit left of the others. */}
|
||||||
className="h-3 w-3 flex-shrink-0 text-primary"
|
|
||||||
aria-label="Active heap (T target)"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{heap.photo_count > 0 ? (
|
{heap.photo_count > 0 ? (
|
||||||
<span className="flex h-5 min-w-[24px] flex-shrink-0 items-center justify-center rounded bg-surface-offset px-1.5 text-xs tabular-nums text-text-muted">
|
<span className="flex h-5 min-w-[24px] flex-shrink-0 items-center justify-center rounded bg-surface-offset px-1.5 text-xs tabular-nums text-text-muted">
|
||||||
{heap.photo_count}
|
{heap.photo_count}
|
||||||
@@ -362,7 +358,7 @@ export function HeapsPanel() {
|
|||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
setActiveMutation.mutate(heap.id)
|
setActiveMutation.mutate(heap.id)
|
||||||
}}
|
}}
|
||||||
className="invisible flex-shrink-0 rounded p-0.5 text-text-muted hover:bg-surface-offset hover:text-text group-hover:visible"
|
className="hidden flex-shrink-0 rounded p-0.5 text-text-muted hover:bg-surface-offset hover:text-text group-hover:block"
|
||||||
title="Set as active heap (T target)"
|
title="Set as active heap (T target)"
|
||||||
aria-label="Set as active heap"
|
aria-label="Set as active heap"
|
||||||
>
|
>
|
||||||
@@ -372,16 +368,18 @@ export function HeapsPanel() {
|
|||||||
|
|
||||||
{/* Kebab menu — collects rename / duplicate / convert /
|
{/* Kebab menu — collects rename / duplicate / convert /
|
||||||
* delete so the row stays compact. */}
|
* delete so the row stays compact. */}
|
||||||
<div className="relative flex-shrink-0">
|
<div
|
||||||
|
className={clsx(
|
||||||
|
'relative flex-shrink-0',
|
||||||
|
isMenuOpen ? 'block' : 'hidden group-hover:block'
|
||||||
|
)}
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
setOpenMenuId(isMenuOpen ? null : heap.id)
|
setOpenMenuId(isMenuOpen ? null : heap.id)
|
||||||
}}
|
}}
|
||||||
className={clsx(
|
className="rounded p-0.5 text-text-muted hover:bg-surface-offset hover:text-text"
|
||||||
'rounded p-0.5 text-text-muted hover:bg-surface-offset hover:text-text',
|
|
||||||
isMenuOpen ? 'visible' : 'invisible group-hover:visible'
|
|
||||||
)}
|
|
||||||
title="More actions"
|
title="More actions"
|
||||||
aria-label="More heap actions"
|
aria-label="More heap actions"
|
||||||
aria-haspopup="menu"
|
aria-haspopup="menu"
|
||||||
|
|||||||
@@ -537,24 +537,28 @@ export function LeftSidebar() {
|
|||||||
<span className="h-5 min-w-[24px] flex-shrink-0" aria-hidden="true" />
|
<span className="h-5 min-w-[24px] flex-shrink-0" aria-hidden="true" />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Folder kebab menu — only on folder rows. Hidden until hover
|
{/* Folder kebab menu — only on folder rows. Hidden (display:none)
|
||||||
* (or when its menu is open) so the count column stays aligned
|
* until hover so it reserves NO width in the resting state and
|
||||||
* in the resting state. */}
|
* the count column stays aligned across folder + non-folder
|
||||||
|
* rows. On hover it appears to the right, pushing the count
|
||||||
|
* left to make room. */}
|
||||||
{item.id.startsWith('folder-') &&
|
{item.id.startsWith('folder-') &&
|
||||||
(() => {
|
(() => {
|
||||||
const folderId = item.id.slice('folder-'.length)
|
const folderId = item.id.slice('folder-'.length)
|
||||||
const isMenuOpen = openMenuId === item.id
|
const isMenuOpen = openMenuId === item.id
|
||||||
return (
|
return (
|
||||||
<div className="relative flex-shrink-0">
|
<div
|
||||||
|
className={clsx(
|
||||||
|
'relative flex-shrink-0',
|
||||||
|
isMenuOpen ? 'block' : 'hidden group-hover:block'
|
||||||
|
)}
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
setOpenMenuId(isMenuOpen ? null : item.id)
|
setOpenMenuId(isMenuOpen ? null : item.id)
|
||||||
}}
|
}}
|
||||||
className={clsx(
|
className="rounded p-0.5 text-text-muted hover:bg-surface-offset hover:text-text"
|
||||||
'rounded p-0.5 text-text-muted hover:bg-surface-offset hover:text-text',
|
|
||||||
isMenuOpen ? 'visible' : 'invisible group-hover:visible'
|
|
||||||
)}
|
|
||||||
title="More actions"
|
title="More actions"
|
||||||
aria-label="More folder actions"
|
aria-label="More folder actions"
|
||||||
aria-haspopup="menu"
|
aria-haspopup="menu"
|
||||||
|
|||||||
Reference in New Issue
Block a user