fix(ui): keep a disabled chosen segment readable and the range rows at 44 px

A faded primary fill reads about 2:1 in light mode, so a disabled chosen
segment swaps to the token pair Button uses instead of the opacity. The
small range rows keep 44 px under a mouse as well, as the chart tabs had,
and the changelog names the fill by what it is.
This commit is contained in:
Marc-André Bombeck committed 2026-10-21 09:36:05 +02:00
1 parent 3c4e07df94
commit 766b413871
3 files changed
+19 -8

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@
drew them on a grey track with the chosen option raised. Above a chart that
read heavier than the chart itself. The shared control now draws what the
dashboard's range tabs always had: no track, the chosen option filled in
the accent colour. The range rows above charts are back to their smaller
the highlight colour. The range rows above charts are back to their smaller
type. Keyboard navigation and the touch size the shared control brought
stay as they are.
@@ -79,7 +79,15 @@ describe("<Segmented>", () => {
const small = html({ size: "sm" });
expect(small).toContain("text-xs");
expect(small).not.toContain("text-sm");
expect(small.match(/pointer-coarse:min-h-11/g)?.length).toBe(2);
expect(small.match(/min-h-11/g)?.length).toBe(2);
});
it("keeps a disabled chosen segment on the readable token pair", () => {
const chosen = html({ disabled: true })
.match(/<button[^>]*>/g)
?.find((b) => b.includes('aria-checked="true"'));
expect(chosen).toContain("disabled:bg-primary-disabled");
expect(chosen).toContain("disabled:opacity-100");
});
it("renders pressed buttons in toggle mode", () => {
+9 -6
View File
@@ -1,8 +1,8 @@
"use client";
/**
* The segmented control: a short row of mutually exclusive choices on one
* track (zoom level, chronicle grouping, cards or table, recent or all,
* The segmented control: a short row of mutually exclusive choices (zoom
* level, chronicle grouping, cards or table, recent or all,
* Paperless-ngx or Papra). One look everywhere, the one the dashboard chart
* tabs always had: no track, the chosen segment filled in the primary colour,
* the others plain until hovered. A muted track with a raised segment was
@@ -26,8 +26,9 @@
* setter that saves a preference is not called twice.
*
* Touch: every segment is at least 44 px on a coarse pointer and 36 px under
* a mouse, the same floor `Button` carries. The four controls this replaced
* sat at 36, 36, 44 and 44.
* a mouse, the same floor `Button` carries; a `sm` range row keeps 44 px
* under a mouse too, as the chart tabs always had. The four controls this
* replaced sat at 36, 36, 44 and 44.
*
* An option with an `icon` and `iconOnly` on the control renders the icon and
* names the segment through `aria-label` and `title`.
@@ -150,11 +151,13 @@ export function Segmented<T extends string>({
iconOnly
? "size-9 pointer-coarse:size-11"
: size === "sm"
? "min-h-9 px-2 sm:px-3 pointer-coarse:min-h-11 pointer-coarse:min-w-11"
? "min-h-11 px-2 sm:px-3 pointer-coarse:min-w-11"
: "min-h-9 px-3 pointer-coarse:min-h-11",
stretch && "flex-1",
checked
? "bg-primary text-primary-foreground hover:bg-primary/90"
? // A faded fill reads ~2:1 in light mode; disabled swaps to
// the token pair `Button` uses instead of the opacity.
"bg-primary text-primary-foreground hover:bg-primary/90 disabled:bg-primary-disabled disabled:text-primary-disabled-foreground disabled:opacity-100"
: "text-foreground hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
)}
>