1import type {
2 NativeStackHeaderItem,
3 NativeStackHeaderItemMenu,
4} from "@react-navigation/native-stack";
5
6import type { HomeListFilterMenu } from "../home/home-list-filter-menu";
7import { withNativeGlassHeaderItem } from "../layout/native-glass-header-items";
8
9type NativeHeaderMenuItems = NativeStackHeaderItemMenu["menu"]["items"];
10type NativeHeaderIcon = NonNullable<Extract<NativeStackHeaderItem, { type: "button" }>["icon"]>;
11
12function sfSymbolIcon(name: string): NativeHeaderIcon {
13 return { type: "sfSymbol", name: name as never };
14}
15
16function toNativeHeaderMenuItems(items: HomeListFilterMenu["items"]): NativeHeaderMenuItems {
17 return items.map((item) =>
18 item.type === "action"
19 ? {
20 type: "action" as const,
21 label: item.title,
22 description: item.subtitle,
23 onPress: item.onPress,
24 state: item.state === "on" ? ("on" as const) : undefined,
25 }
26 : {
27 type: "submenu" as const,
28 label: item.title,
29 items: toNativeHeaderMenuItems(item.items),
30 },
31 );
32}
33
34/**
35 * Right-side UINavigationBar items for the sidebar column: the thread list
36 * filter/sort menu plus the settings button, sharing one glass capsule —
37 * the Messages-style grouped header buttons. The embedded sidebar keeps these
38 * beside its title; only the detail column uses the Duo's vertical bar.
39 */
40export function createSidebarHeaderItems(input: {
41 readonly filterIcon: string;
42 readonly filterMenu: HomeListFilterMenu;
43 readonly onOpenSettings: () => void;
44}): NativeStackHeaderItem[] {
45 return [
46 withNativeGlassHeaderItem({
47 type: "menu",
48 axisBehavior: "horizontalOnly",
49 label: "",
50 accessibilityLabel: "Filter threads",
51 icon: sfSymbolIcon(input.filterIcon),
52 menu: {
53 title: input.filterMenu.title,
54 items: toNativeHeaderMenuItems(input.filterMenu.items),
55 },
56 }),
57 withNativeGlassHeaderItem({
58 type: "button",
59 axisBehavior: "horizontalOnly",
60 label: "Settings",
61 accessibilityLabel: "Open settings",
62 icon: sfSymbolIcon("gearshape"),
63 onPress: input.onOpenSettings,
64 }),
65 ];
66}