fix: assorted UI polish from review pass
- FilterPill: drop the inline value text from the active state. Pills now stay the same width whether or not a filter is set; the popover is the canonical place to read the value, and the title attribute surfaces it on hover. - TopBar: remove the search input — search lives in the filter bar now. - FilterBar: add a search input on the left, with the pill cluster centered between it and a flex-shrink-0 Clear-all on the right. - LeftSidebar / HeapsPanel: count badges use a fixed-width slot (h-5 min-w-[24px], tabular-nums) so counts line up in the same visual column across rows. Empty rows reserve the slot. - LeftSidebar: pull section counts (All Photos, Rated, Duplicates, Discarded) from a new useLibraryStatsQuery hook backed by the expanded /library/stats endpoint. Tags count was already wired. - backend/library: stats endpoint returns per-section counts that match the filter the sidebar applies on click. - Stats invalidation hooked into the standard photo-mutation paths. - RightSidebar header: h-12 to match TopBar height. - Timeline sticky date overlay: only show once the natural in-grid header has scrolled OUT of the viewport. Avoids the duplicate-label flash when both labels would be visible. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -338,19 +338,23 @@ export function HeapsPanel() {
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* Right-aligned action cluster: active indicator, count,
|
||||
* target toggle, kebab menu. The flex-1 on the name span
|
||||
* pushes everything below to the right edge of the row. */}
|
||||
{/* Right-aligned cluster. Active indicator + count are
|
||||
* always visible; set-active and kebab appear on hover
|
||||
* to the RIGHT of the count, displacing it slightly so
|
||||
* the count column lines up with the rest of the
|
||||
* sidebar in the resting state. */}
|
||||
{isActive && (
|
||||
<Target
|
||||
className="h-3 w-3 flex-shrink-0 text-primary"
|
||||
aria-label="Active heap (T target)"
|
||||
/>
|
||||
)}
|
||||
{heap.photo_count > 0 && (
|
||||
<span className="flex-shrink-0 rounded bg-surface-offset px-1.5 py-0.5 text-xs text-text-muted">
|
||||
{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">
|
||||
{heap.photo_count}
|
||||
</span>
|
||||
) : (
|
||||
<span className="h-5 min-w-[24px] flex-shrink-0" aria-hidden="true" />
|
||||
)}
|
||||
{!isActive && (
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user