返回 presentation-ai
pyramid-height-context.tsx
根目录 / src / components / notebook / presentation / editor / custom-elements / pyramid-height-context.tsx
1 "use client";
2
3 import {
4 createContext,
5 useCallback,
6 useContext,
7 useMemo,
8 useState,
9 type ReactNode,
10 } from "react";
11
12 type PyramidHeightContextValue = {
13 maxShapeHeight: number | null;
14 registerItemHeight: (itemKey: string, height: number) => void;
15 unregisterItemHeight: (itemKey: string) => void;
16 };
17
18 const PyramidHeightContext = createContext<PyramidHeightContextValue>({
19 maxShapeHeight: null,
20 registerItemHeight: () => {},
21 unregisterItemHeight: () => {},
22 });
23
24 export function PyramidHeightProvider({ children }: { children: ReactNode }) {
25 const [itemHeights, setItemHeights] = useState<Map<string, number>>(
26 () => new Map(),
27 );
28
29 const registerItemHeight = useCallback((itemKey: string, height: number) => {
30 setItemHeights((currentHeights) => {
31 if (currentHeights.get(itemKey) === height) return currentHeights;
32
33 const nextHeights = new Map(currentHeights);
34 nextHeights.set(itemKey, height);
35 return nextHeights;
36 });
37 }, []);
38
39 const unregisterItemHeight = useCallback((itemKey: string) => {
40 setItemHeights((currentHeights) => {
41 if (!currentHeights.has(itemKey)) return currentHeights;
42
43 const nextHeights = new Map(currentHeights);
44 nextHeights.delete(itemKey);
45 return nextHeights;
46 });
47 }, []);
48
49 const maxShapeHeight = useMemo(() => {
50 if (itemHeights.size === 0) return null;
51 return Math.max(...itemHeights.values());
52 }, [itemHeights]);
53
54 const value = useMemo(
55 () => ({
56 maxShapeHeight,
57 registerItemHeight,
58 unregisterItemHeight,
59 }),
60 [maxShapeHeight, registerItemHeight, unregisterItemHeight],
61 );
62
63 return (
64 <PyramidHeightContext.Provider value={value}>
65 {children}
66 </PyramidHeightContext.Provider>
67 );
68 }
69
70 export function usePyramidHeight() {
71 return useContext(PyramidHeightContext);
72 }
73
73 lines Plain Text