| 1 | import { type TElement, type TText } from "platejs"; |
| 2 | import { type PlateEditor } from "platejs/react"; |
| 3 | import { useEffect, useRef } from "react"; |
| 4 | |
| 5 | import { updateSiblingsForcefully } from "@/components/notebook/presentation/editor/dnd/utils/updateSiblingsForcefully"; |
| 6 | |
| 7 | /** |
| 8 | * Forces re-render of all children of the given element whenever |
| 9 | * the number of its children changes. This is useful for components |
| 10 | * whose UI depends on sibling indexes/count. |
| 11 | */ |
| 12 | export function useForceUpdateChildrenOnLengthChange( |
| 13 | editor: PlateEditor | null | undefined, |
| 14 | element: (TElement | TText) | null | undefined, |
| 15 | ): void { |
| 16 | const previousLengthRef = useRef<number>( |
| 17 | Array.isArray((element as TElement | TText | undefined)?.children) |
| 18 | ? ((element as TElement).children as unknown[]).length |
| 19 | : 0, |
| 20 | ); |
| 21 | |
| 22 | useEffect(() => { |
| 23 | if (!editor || !element) return; |
| 24 | |
| 25 | const currentLength = Array.isArray((element as TElement).children) |
| 26 | ? ((element as TElement).children as unknown[]).length |
| 27 | : 0; |
| 28 | |
| 29 | if (currentLength !== previousLengthRef.current) { |
| 30 | const parentPath = editor.api.findPath(element as TElement); |
| 31 | if (parentPath) { |
| 32 | updateSiblingsForcefully(editor, element as TElement, parentPath); |
| 33 | } |
| 34 | previousLengthRef.current = currentLength; |
| 35 | } |
| 36 | }, [editor, element, (element as TElement | undefined)?.children?.length]); |
| 37 | } |
| 38 |