From 0c3baf04c5b53f06ef171ead6fb397586fb84358 Mon Sep 17 00:00:00 2001 From: Matt Ciaccio Date: Wed, 29 Apr 2026 14:11:27 +0200 Subject: [PATCH] feat(mobile): add MobileLayoutProvider context + useMobileChrome hook --- .../layout/mobile/mobile-layout-provider.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/components/layout/mobile/mobile-layout-provider.tsx diff --git a/src/components/layout/mobile/mobile-layout-provider.tsx b/src/components/layout/mobile/mobile-layout-provider.tsx new file mode 100644 index 0000000..4a96be6 --- /dev/null +++ b/src/components/layout/mobile/mobile-layout-provider.tsx @@ -0,0 +1,46 @@ +'use client'; + +import { createContext, useContext, useMemo, useState, type ReactNode } from 'react'; + +type MobileChromeState = { + title: string | null; + primaryAction: ReactNode | null; + showBackButton: boolean; +}; + +type MobileChromeApi = MobileChromeState & { + setChrome: (next: Partial) => void; +}; + +const MobileChromeContext = createContext(null); + +export function MobileLayoutProvider({ children }: { children: ReactNode }) { + const [state, setState] = useState({ + title: null, + primaryAction: null, + showBackButton: false, + }); + + const value = useMemo( + () => ({ + ...state, + setChrome: (next) => setState((prev) => ({ ...prev, ...next })), + }), + [state], + ); + + return {children}; +} + +/** + * Page-level hook to push a title / back-button / primary action into the + * mobile topbar. The provider is only mounted by ``, so + * desktop-shell renders never call into this context. + */ +export function useMobileChrome() { + const ctx = useContext(MobileChromeContext); + if (!ctx) { + throw new Error('useMobileChrome must be used inside '); + } + return ctx; +}