Skip to content

Commit d90ff40

Browse files
fix(spa): move Customize onto the filter row, after Clear all (#554)
Closes #554. The header right-side now carries only the +Add primary action; Customize moves into the FilterBar's `trailing` slot so the filter row reads as one self-contained unit: … filter chips | Clear all | Customize `Clear all` continues to hide when no filter is active (already wired that way). `Customize` is always visible — it's a column-affordance, independent of filter state. Both buttons use the same row-aligned `py-1.5` size so the chrome lines up cleanly. No second toolbar row, no dangling chrome — matches the "no redundant chrome" rule. - typecheck + eslint + stylelint + **dark-mode guard** clean. - vitest: 142 passed (unchanged). - `pnpm -r build` ok. Closes #554 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 418a730 commit d90ff40

1 file changed

Lines changed: 34 additions & 23 deletions

File tree

frontend/apps/web/src/pages/ListPage.tsx

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -503,24 +503,12 @@ export function ListPage() {
503503
/>
504504
<h1 className="text-2xl font-semibold">{listTitle}</h1>
505505
</div>
506-
{/* Customize sits to the LEFT of the + Add button (#94). */}
506+
{/* Header right-side: only the +Add primary action lives here.
507+
Customize moved to the FilterBar trailing slot in #554 so the
508+
filter row is one self-contained unit (… filter chips |
509+
Clear all | Customize) — no second toolbar row, no dangling
510+
chrome. */}
507511
<div className="flex shrink-0 items-center gap-2">
508-
<button
509-
type="button"
510-
onClick={() => setColsOpen(true)}
511-
aria-haspopup="dialog"
512-
aria-label="Customize columns"
513-
title="Customize columns"
514-
className="inline-flex shrink-0 items-center gap-1.5 rounded-md border border-gray-300 px-3 py-2 text-sm hover:bg-gray-100"
515-
>
516-
<Settings2 className="h-4 w-4" aria-hidden />
517-
Customize
518-
{hiddenCols.size > 0 && (
519-
<span className="ml-0.5 rounded-full bg-gray-500 px-1.5 py-0.5 text-xs text-white">
520-
{hiddenCols.size} hidden
521-
</span>
522-
)}
523-
</button>
524512
{data.permissions.add && (
525513
<Link
526514
to={withPreservedFilters(`/${appLabel}/${modelName}/add`, searchParams.toString())}
@@ -582,17 +570,40 @@ export function ListPage() {
582570
) : null
583571
}
584572
trailing={
585-
activeFilterCount > 0 ? (
573+
// Filter-row trailing slot (#554): "Clear all" (only when at
574+
// least one filter is selected — nothing to clear, no button)
575+
// and "Customize" (always visible — it's the column-customizer
576+
// affordance, independent of filter state) as the last two
577+
// buttons on the row, in that order.
578+
<>
579+
{activeFilterCount > 0 && (
580+
<button
581+
type="button"
582+
onClick={() => patchParams((next) => filters.forEach((f) => next.delete(f.name)))}
583+
title="Clear all filters"
584+
className="inline-flex shrink-0 items-center gap-1.5 rounded-md border border-gray-300 px-3 py-1.5 text-sm hover:bg-gray-100"
585+
>
586+
<X className="h-4 w-4" aria-hidden />
587+
Clear all
588+
</button>
589+
)}
586590
<button
587591
type="button"
588-
onClick={() => patchParams((next) => filters.forEach((f) => next.delete(f.name)))}
589-
title="Clear all filters"
592+
onClick={() => setColsOpen(true)}
593+
aria-haspopup="dialog"
594+
aria-label="Customize columns"
595+
title="Customize columns"
590596
className="inline-flex shrink-0 items-center gap-1.5 rounded-md border border-gray-300 px-3 py-1.5 text-sm hover:bg-gray-100"
591597
>
592-
<X className="h-4 w-4" aria-hidden />
593-
Clear all
598+
<Settings2 className="h-4 w-4" aria-hidden />
599+
Customize
600+
{hiddenCols.size > 0 && (
601+
<span className="ml-0.5 rounded-full bg-gray-500 px-1.5 py-0.5 text-xs text-white">
602+
{hiddenCols.size} hidden
603+
</span>
604+
)}
594605
</button>
595-
) : null
606+
</>
596607
}
597608
/>
598609

0 commit comments

Comments
 (0)