mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 08:13:50 +00:00
48 lines
1.9 KiB
TypeScript
48 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { createContext, useContext } from "react";
|
|
import type { ProPaneId } from "@/stores/pro-tab-store";
|
|
|
|
/**
|
|
* Which Pro pane hosts the current subtree. `null` means "not inside a Pro
|
|
* pane" (standard shell). Set by the Pro shell's Pane component so that
|
|
* pane-hosted apps can know which side of the split they live on (e.g. the
|
|
* mail app routing a double-clicked email to the opposite pane) and so that
|
|
* overlay chrome can scope itself to the pane.
|
|
*/
|
|
export const PaneIdContext = createContext<ProPaneId | null>(null);
|
|
|
|
export function usePaneId(): ProPaneId | null {
|
|
return useContext(PaneIdContext);
|
|
}
|
|
|
|
/**
|
|
* True when the current subtree is the *focused* Pro tab: the active tab of
|
|
* the focused pane. Exactly one tab body sees `true` at any time, which is
|
|
* what lets that tab own shared, single-instance concerns - currently the
|
|
* address bar, where the focused tab's permalink is reflected. Always false
|
|
* outside the Pro shell.
|
|
*/
|
|
export const ProTabFocusContext = createContext<boolean>(false);
|
|
|
|
export function useIsFocusedProTab(): boolean {
|
|
return useContext(ProTabFocusContext);
|
|
}
|
|
|
|
/**
|
|
* True when the current subtree renders inside a Pro pane.
|
|
*
|
|
* Overlays that go `fixed inset-0` in a mobile layout must switch to
|
|
* `absolute` positioning when this is true: inside a pane, "mobile" means
|
|
* the *pane* is phone-sized while the viewport is desktop-sized, so a
|
|
* viewport-fixed overlay would escape the pane and cover the whole app -
|
|
* and viewport CSS breakpoints (`sm:hidden` etc.) must not be trusted for
|
|
* the same reason. Each Pro tab body is an `absolute inset-0` wrapper and
|
|
* the email viewer root is `relative`, so pane-filling absolute overlays
|
|
* resolve to the pane without needing portals (and stay hidden with their
|
|
* tab when it's inactive).
|
|
*/
|
|
export function useIsPaneScoped(): boolean {
|
|
return useContext(PaneIdContext) !== null;
|
|
}
|