polish(plex): match the feed rail's segmented-pill look for the any/all toggle
The genre + actor MATCH toggles were a boxed button row (rounded-lg border, no track); restyle them as the feed rail's tag-match toggle — a rounded-full track (border + bg-card + p-0.5) with an inset rounded-full active pill, plus a MATCH label. Extracted a shared MatchToggle so both read identically. i18n plex.filter.matchLabel (en/hu). (Plex cast-explore polish)
This commit is contained in:
@@ -33,6 +33,43 @@ const DURATION_BUCKETS: { key: string; min: number | null; max: number | null }[
|
|||||||
{ key: "long", min: 120 * 60, max: null },
|
{ key: "long", min: 120 * 60, max: null },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// The any/all combine toggle for a multi-value filter (genres, actors). Same segmented-pill look as
|
||||||
|
// the feed rail's tag MATCH toggle (rounded-full track + inset active pill), not a boxed button row.
|
||||||
|
function MatchToggle({
|
||||||
|
mode,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
mode: "any" | "all";
|
||||||
|
onChange: (m: "any" | "all") => void;
|
||||||
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<div className="mb-1.5 flex items-center justify-between">
|
||||||
|
<span className="text-[10px] uppercase tracking-wide text-muted">
|
||||||
|
{t("plex.filter.matchLabel")}
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
className="flex items-center rounded-full border border-border bg-card p-0.5 text-[10px]"
|
||||||
|
role="group"
|
||||||
|
aria-label={t("plex.filter.matchLabel")}
|
||||||
|
>
|
||||||
|
{(["any", "all"] as const).map((m) => (
|
||||||
|
<button
|
||||||
|
key={m}
|
||||||
|
onClick={() => onChange(m)}
|
||||||
|
aria-pressed={mode === m}
|
||||||
|
className={`rounded-full px-2 py-0.5 transition ${
|
||||||
|
mode === m ? "bg-accent text-accent-fg" : "text-muted hover:text-fg"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{t(`plex.filter.match.${m}`)}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function PlexSidebar({
|
export default function PlexSidebar({
|
||||||
layout,
|
layout,
|
||||||
setLayout,
|
setLayout,
|
||||||
@@ -212,20 +249,11 @@ export default function PlexSidebar({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{filters.actors.length > 1 && (
|
{filters.actors.length > 1 && (
|
||||||
<div className="w-full inline-flex overflow-hidden rounded-lg border border-border text-[11px]">
|
<div className="w-full">
|
||||||
{(["any", "all"] as const).map((m) => (
|
<MatchToggle
|
||||||
<button
|
mode={filters.actorMode ?? "any"}
|
||||||
key={m}
|
onChange={(m) => patch({ actorMode: m })}
|
||||||
onClick={() => patch({ actorMode: m })}
|
/>
|
||||||
className={`px-2 py-0.5 transition ${
|
|
||||||
(filters.actorMode ?? "any") === m
|
|
||||||
? "bg-accent text-accent-fg"
|
|
||||||
: "text-muted hover:bg-surface"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{t(`plex.filter.match.${m}`)}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{filters.actors.map((a) => (
|
{filters.actors.map((a) => (
|
||||||
@@ -312,21 +340,10 @@ export default function PlexSidebar({
|
|||||||
body: (
|
body: (
|
||||||
<>
|
<>
|
||||||
{filters.genres.length > 1 && (
|
{filters.genres.length > 1 && (
|
||||||
<div className="mb-1.5 inline-flex overflow-hidden rounded-lg border border-border text-[11px]">
|
<MatchToggle
|
||||||
{(["any", "all"] as const).map((m) => (
|
mode={filters.genreMode ?? "any"}
|
||||||
<button
|
onChange={(m) => patch({ genreMode: m })}
|
||||||
key={m}
|
/>
|
||||||
onClick={() => patch({ genreMode: m })}
|
|
||||||
className={`px-2 py-0.5 transition ${
|
|
||||||
(filters.genreMode ?? "any") === m
|
|
||||||
? "bg-accent text-accent-fg"
|
|
||||||
: "text-muted hover:bg-surface"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{t(`plex.filter.match.${m}`)}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
<ChipRow>
|
<ChipRow>
|
||||||
{facets.genres.map((g) => (
|
{facets.genres.map((g) => (
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
},
|
},
|
||||||
"collection": "Collection",
|
"collection": "Collection",
|
||||||
"collectionSearch": "Search collections…",
|
"collectionSearch": "Search collections…",
|
||||||
"collectionEmpty": "No collections"
|
"collectionEmpty": "No collections",
|
||||||
|
"matchLabel": "Match"
|
||||||
},
|
},
|
||||||
"count": "{{count}} titles",
|
"count": "{{count}} titles",
|
||||||
"searchCount": "{{count}} matches",
|
"searchCount": "{{count}} matches",
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
},
|
},
|
||||||
"collection": "Kollekció",
|
"collection": "Kollekció",
|
||||||
"collectionSearch": "Kollekciók keresése…",
|
"collectionSearch": "Kollekciók keresése…",
|
||||||
"collectionEmpty": "Nincs kollekció"
|
"collectionEmpty": "Nincs kollekció",
|
||||||
|
"matchLabel": "Egyezés"
|
||||||
},
|
},
|
||||||
"count": "{{count}} cím",
|
"count": "{{count}} cím",
|
||||||
"searchCount": "{{count}} találat",
|
"searchCount": "{{count}} találat",
|
||||||
|
|||||||
Reference in New Issue
Block a user