Skip to content
Source
Sign inSign up

useSystemWorkspaceTabBar.ts

65 lines2.4 KB

1import { isDuoDevice } from "../../../lib/device-type";
2import { Platform } from "react-native";
3import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../../../native/native-glass";
4import { useAdaptiveWorkspaceLayout } from "../adaptive-workspace-context";
5import { useDeviceType, useNativeLayoutMetrics } from "../../../native/native-layout-metrics";
6import { useWorkspaceTabs } from "./WorkspaceTabsContext";
7import { workspaceUsesColumns } from "./workspace-tabs-state";
8​
9function useWorkspacePage() {
10 const workspace = useWorkspaceTabs();
11 return (
12 workspace !== null && !workspaceUsesColumns(workspace.state.selectedTab, workspace.settingsOpen)
13 );
15​
16export function useSidebarWorkspaceTabs(): "picker" | "toolbar" | null {
17 const { layout } = useAdaptiveWorkspaceLayout();
18 const deviceType = useDeviceType();
19 const metrics = useNativeLayoutMetrics();
20 const page = useWorkspacePage();
21 if (Platform.OS !== "ios" || !layout.usesSplitView || page) return null;
22 if (deviceType === "pad") return null;
23 // Portrait Duo has no system rail; keep its tabs in the sidebar like iPad.
24 if (deviceType === "duo-unfolded" && (metrics?.verticalBarEdge ?? "none") === "none")
25 return "picker";
26 return (metrics?.verticalBarEdge ?? "none") === "none" ? "toolbar" : null;
28​
29export function useCompactWorkspaceTabs() {
30 const { layout } = useAdaptiveWorkspaceLayout();
31 const deviceType = useDeviceType();
32 // The compact glass picker reserves the trailing edge for a separate compose button.
33 return (
34 Platform.OS === "ios" &&
35 deviceType !== "pad" &&
36 !layout.usesSplitView &&
37 !isDuoDevice(deviceType)
38 );
40​
41/** The workspace tab bar floats with compose beside it. Before iOS 26 UITabBar is opaque and
42 * full width, so it sits flush and compose stays in the header. */
43export function useFloatingWorkspaceTabs() {
44 const { layout } = useAdaptiveWorkspaceLayout();
45 const deviceType = useDeviceType();
46 const compactTabs = useCompactWorkspaceTabs();
47 return (
48 NATIVE_LIQUID_GLASS_SUPPORTED &&
49 (compactTabs || (deviceType === "pad" && !layout.usesSplitView))
50 );
52​
53export function useSystemWorkspaceTabBar() {
54 const deviceType = useDeviceType();
55 const { layout } = useAdaptiveWorkspaceLayout();
56 const sidebarTabs = useSidebarWorkspaceTabs();
57 const compactTabs = useCompactWorkspaceTabs();
58 return (
59 Platform.OS === "ios" &&
60 deviceType !== "pad" &&
61 layout.variant !== "medium" &&
62 sidebarTabs === null &&
63 !compactTabs
64 );