Files
Endoleap/src/components/workspace/active-board.tsx
T

31 lines
1.6 KiB
TypeScript

/**
* 侧栏与画布页面共享的当前board元数据Context。只保存ID、工作区、路由引用与标题,
* 不保存元素、加载任务或ProjectEngine;目录改名可更新标题而无需重建业务画布。
*/
"use client";
import { createContext, useContext, useMemo, useState, type Dispatch, type ReactNode, type SetStateAction } from "react";
import type { Board } from "@/lib/workspace";
/** null代表当前没有已解析画布,workspace_ref保留路径slug/引用与真实workspace_id的对应关系。 */
type ActiveBoard = (Pick<Board, "id" | "workspace_id" | "title" | "slug"> & { workspace_ref?: string }) | null;
/** 暴露React状态setter,调用方可条件更新以免迟到改名覆盖另一个活动board。 */
const ActiveBoardContext = createContext<{
board: ActiveBoard;
setBoard: Dispatch<SetStateAction<ActiveBoard>>;
} | null>(null);
/** 在工作台布局内保持元数据,useMemo稳定Context对象,避免只因父渲染就通知全部使用方。 */
export function ActiveBoardProvider({ children }: { children: ReactNode }) {
const [board, setBoard] = useState<ActiveBoard>(null);
const value = useMemo(() => ({ board, setBoard }), [board]);
return <ActiveBoardContext.Provider value={value}>{children}</ActiveBoardContext.Provider>;
}
/** 缺少Provider时拒绝读取;不从浏览器路径凭空构造一条已认证board记录。 */
export function useActiveBoard() {
const context = useContext(ActiveBoardContext);
if (!context) throw new Error("useActiveBoard requires ActiveBoardProvider");
return context;
}