fix(feed): give the view switcher the keyboard model its menu role promises

Arrows/Home/End move a roving focus and Escape hands focus back to the
trigger — the menu unmounts under the focused item, which stranded focus
on <body>. Outside-click deliberately does not refocus: that would steal
focus from whatever was just clicked.
This commit is contained in:
2026-07-16 02:36:56 +02:00
parent eae65456ac
commit 805441ac58
3 changed files with 69 additions and 10 deletions
+3 -2
View File
@@ -4,9 +4,10 @@
export type FeedView = "cards" | "rows";
export const FEED_VIEWS: readonly FeedView[] = ["cards", "rows"] as const;
export const FEED_VIEW_DEFAULT: FeedView = "cards";
export function isFeedView(v: unknown): v is FeedView {
const FEED_VIEW_DEFAULT: FeedView = "cards";
function isFeedView(v: unknown): v is FeedView {
return typeof v === "string" && (FEED_VIEWS as readonly string[]).includes(v);
}
+4 -2
View File
@@ -17,8 +17,10 @@ export const LS = {
defaultViewFilters: "siftlode.defaultViewFilters",
page: "siftlode.page",
perfMode: "siftlode.perfMode",
// The feed's view mode (see lib/feedView.ts). A local cache of the server pref, so the feed
// renders in your chosen view on first paint instead of flashing the default.
// The feed's view mode (see lib/feedView.ts) — a cache of the server pref, so a reload of an
// established tab paints your view straight away. A brand-new tab still starts on the default
// until /api/me lands: the account isn't pinned yet (App pins it once meQuery resolves), so
// the per-account key can't be read.
feedView: "siftlode.feedView",
channelFilter: "siftlode.channelFilter",
channelsView: "siftlode.channelsView",