type TipTapNode = { type?: string text?: string content?: TipTapNode[] } /** True when TipTap JSON has no meaningful text (blank doc / empty paragraph). */ export function isEmptyTipTapDoc(content: Record | null | undefined): boolean { if (!content) return true return !tipTapNodeHasText(content as TipTapNode) } function tipTapNodeHasText(node: TipTapNode | TipTapNode[] | null | undefined): boolean { if (!node) return false if (Array.isArray(node)) { return node.some((child) => tipTapNodeHasText(child)) } if (typeof node.text === "string" && node.text.trim() !== "") { return true } if (Array.isArray(node.content)) { return node.content.some((child) => tipTapNodeHasText(child)) } return false }