feat(feed): convert the Source filter to the FilterSelect dropdown

Replaces the native <select> "Source" control with a labeled FilterSelect pill, matching
the Watch state / Content types pills — one consistent toolbar idiom. Single-select over
the three librarySource values (organic / all / search-only).

Sort and View are intentionally left as-is: Sort is a two-dimensional key+direction control
(plus reshuffle and a tables-only "no sort") shared across five surfaces, and View is already
on the same AnchoredPopover platform with an icon-only trigger tuned for this packed toolbar —
FilterSelect's text trigger would regress it. Neither fits FilterSelect's one-dimensional model.
This commit is contained in:
2026-08-21 17:36:33 +02:00
parent 5851ddd329
commit 6109e0c6f1
+16 -18
View File
@@ -598,24 +598,22 @@ export default function Feed({
{!channelScoped && ( {!channelScoped && (
<> <>
<span className="mx-1 h-5 w-px bg-border" aria-hidden="true" /> <span className="mx-1 h-5 w-px bg-border" aria-hidden="true" />
<label className="inline-flex items-center gap-1.5 text-xs text-muted"> <FilterSelect
<span>{t("feed.source.label")}</span> label={t("feed.source.label")}
<select testId="feed-source"
value={filters.librarySource ?? "organic"} options={[
onChange={(e) => { value: "organic", label: t("feed.source.organic") },
setFilters({ { value: "all", label: t("feed.source.all") },
...filters, { value: "search", label: t("feed.source.only") },
librarySource: e.target.value as FeedFilters["librarySource"], ]}
}) selected={[filters.librarySource ?? "organic"]}
} onChange={(next) =>
title={t("feed.source.tip")} setFilters({
className="bg-surface border border-border rounded-lg px-2 py-1 text-xs focus:outline-hidden focus:ring-2 focus:ring-accent/40" ...filters,
> librarySource: next[0] as FeedFilters["librarySource"],
<option value="organic">{t("feed.source.organic")}</option> })
<option value="all">{t("feed.source.all")}</option> }
<option value="search">{t("feed.source.only")}</option> />
</select>
</label>
</> </>
)} )}
<span className="mx-1 h-5 w-px bg-border" aria-hidden="true" /> <span className="mx-1 h-5 w-px bg-border" aria-hidden="true" />