fix(plex): the player's settings panel is a tab list with named, touch-sized rows
- Its section switch is `ui/Tabs` (new `tone="media"` paint for the dark chrome) with a wired tabpanel; the panel opens with the focus on the selected tab. - On/off rows are `CheckRow` (the whole row, 44 on touch), the "no background" checkbox too. - Every slider and the four colour wells carry the name their row shows. - The clock's date-style buttons reach the touch target.
This commit is contained in:
@@ -15,6 +15,8 @@ import CountBadge from "./CountBadge";
|
||||
// ONE Tab stop (the selected tab; roving tabindex), the arrows move and select (either axis, since the
|
||||
// vertical rail is a row below `sm`), Home/End jump to the ends. The panel it controls is wired with
|
||||
// `useTabPanel`: the tabs point at it (`aria-controls`) and it is labelled by the selected tab.
|
||||
// `tone="media"` is the same list painted for the player's dark chrome (the Plex player's settings
|
||||
// panel), which looks the same on every theme because the picture under it does.
|
||||
|
||||
export interface TabDef {
|
||||
id: string;
|
||||
@@ -32,6 +34,7 @@ export default function Tabs({
|
||||
className,
|
||||
idBase,
|
||||
label,
|
||||
tone,
|
||||
}: {
|
||||
tabs: TabDef[];
|
||||
active: string;
|
||||
@@ -45,6 +48,8 @@ export default function Tabs({
|
||||
idBase?: string;
|
||||
/** The tab list's accessible name, when the page heading beside it does not say what it switches. */
|
||||
label?: string;
|
||||
/** Painted for the media chrome instead of the page (equal-width, white on black). */
|
||||
tone?: "media";
|
||||
}) {
|
||||
const ownBase = useId();
|
||||
const base = idBase ?? ownBase;
|
||||
@@ -100,11 +105,17 @@ export default function Tabs({
|
||||
tabIndex={tb.id === stop ? 0 : -1}
|
||||
data-testid={tb.testId}
|
||||
onClick={() => onChange(tb.id)}
|
||||
className={`pill touch-target items-center rounded-lg px-3 text-sm ${
|
||||
vertical
|
||||
? "inline-flex shrink-0 gap-1.5 py-1.5 sm:flex sm:w-full sm:justify-start sm:gap-2 sm:py-2 sm:text-left"
|
||||
: "inline-flex gap-1.5 py-1.5"
|
||||
} ${on ? "font-medium shadow-md shadow-accent/20" : "state-layer"}`}
|
||||
className={
|
||||
tone === "media"
|
||||
? `touch-target flex-1 items-center justify-center whitespace-nowrap rounded px-2 py-1 text-2xs ${
|
||||
on ? "bg-white/15 text-accent" : "text-white/70 hover:bg-white/10"
|
||||
}`
|
||||
: `pill touch-target items-center rounded-lg px-3 text-sm ${
|
||||
vertical
|
||||
? "inline-flex shrink-0 gap-1.5 py-1.5 sm:flex sm:w-full sm:justify-start sm:gap-2 sm:py-2 sm:text-left"
|
||||
: "inline-flex gap-1.5 py-1.5"
|
||||
} ${on ? "font-medium shadow-md shadow-accent/20" : "state-layer"}`
|
||||
}
|
||||
>
|
||||
{Icon && <Icon className="h-4 w-4 shrink-0" />}
|
||||
{tb.label}
|
||||
|
||||
@@ -27,7 +27,7 @@ const PLAIN: Record<string, [number, string]> = {
|
||||
"PlaylistsRail.tsx": [1, "the load-error retry"],
|
||||
"PlexCollectionEditor.tsx": [1, "a checkbox row in a picker"],
|
||||
"PlexInfo.tsx": [1, "the rating filter (a number)"],
|
||||
"PlexPlayerSettings.tsx": [2, "setting options"],
|
||||
"PlexPlayerSettings.tsx": [1, "the clock's date-style options"],
|
||||
"PlexPlaylistAdd.tsx": [1, "a checkbox row in a picker"],
|
||||
"PlexPlaylistView.tsx": [1, "a show's poster stack (aria-hidden)"],
|
||||
"PlexSearchBox.tsx": [1, "a listbox option"],
|
||||
|
||||
Reference in New Issue
Block a user