42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
|
|
import {
|
||
|
|
createContext,
|
||
|
|
useContext,
|
||
|
|
useEffect,
|
||
|
|
useState,
|
||
|
|
type PropsWithChildren,
|
||
|
|
} from "react";
|
||
|
|
|
||
|
|
type PageTitleCtx = {
|
||
|
|
title: string | null;
|
||
|
|
setTitle: (title: string | null) => void;
|
||
|
|
};
|
||
|
|
|
||
|
|
const PageTitleContext = createContext<PageTitleCtx | null>(null);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Lets a page publish its title to the global header so the header can show the
|
||
|
|
* current page name (e.g. "全部资料" / "热门资料") in place of the brand, avoiding
|
||
|
|
* a separate on-page title row. Pages that don't set one fall back to the brand.
|
||
|
|
*/
|
||
|
|
export function PageTitleProvider({ children }: PropsWithChildren) {
|
||
|
|
const [title, setTitle] = useState<string | null>(null);
|
||
|
|
return (
|
||
|
|
<PageTitleContext.Provider value={{ title, setTitle }}>
|
||
|
|
{children}
|
||
|
|
</PageTitleContext.Provider>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function usePageTitle(): string | null {
|
||
|
|
return useContext(PageTitleContext)?.title ?? null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Publish the current page's title; clears it again when the page unmounts. */
|
||
|
|
export function useSetPageTitle(title: string | null): void {
|
||
|
|
const setTitle = useContext(PageTitleContext)?.setTitle;
|
||
|
|
useEffect(() => {
|
||
|
|
setTitle?.(title);
|
||
|
|
return () => setTitle?.(null);
|
||
|
|
}, [setTitle, title]);
|
||
|
|
}
|