import { useCallback, useState } from "react"; import { downloadMarkdownAsDocx, downloadMarkdownAsPdf, type DocxOptions, type PdfOptions, } from "./converter"; /** * Markdown 下载 Hook 配置选项 */ export interface UseMarkdownDownloadOptions { /** * 下载开始时的回调 */ onDownloadStart?: (format: "docx" | "pdf") => void; /** * 下载完成时的回调 */ onDownloadEnd?: (format: "docx" | "pdf") => void; /** * 下载失败时的回调 */ onError?: (error: Error, format: "docx" | "pdf") => void; } /** * Markdown 下载 Hook 返回值 */ export interface UseMarkdownDownloadReturn { /** * 当前下载状态 */ isDownloading: "docx" | "pdf" | null; /** * 下载为 DOCX */ downloadAsDocx: ( markdown: string, filename: string, options?: DocxOptions, ) => Promise; /** * 下载为 PDF */ downloadAsPdf: ( markdown: string, filename: string, options?: PdfOptions & { resolveAssetUrl?: (rawPath: string) => string | null | Promise; }, ) => Promise; /** * 是否可以下载(没有正在进行的下载) */ canDownload: boolean; } /** * Markdown 文档下载 Hook * * @description * 将 Markdown 内容转换为 DOCX 或 PDF 格式并下载。 * 可在任何 React + TypeScript 项目中使用。 * * @example * ```tsx * import { useMarkdownDownload } from "./hooks/use-markdown-download"; * * function MyComponent() { * const { downloadAsDocx, downloadAsPdf, isDownloading, canDownload } = useMarkdownDownload({ * onError: (error, format) => { * console.error(`Failed to download as ${format}:`, error); * }, * }); * * const handleDownload = () => { * downloadAsDocx("# Hello World", "document"); * }; * * return ( * * ); * } * ``` */ export function useMarkdownDownload( options: UseMarkdownDownloadOptions = {}, ): UseMarkdownDownloadReturn { const { onDownloadStart, onDownloadEnd, onError } = options; const [isDownloading, setIsDownloading] = useState<"docx" | "pdf" | null>( null, ); const downloadAsDocx = useCallback( async (markdown: string, filename: string, options?: DocxOptions) => { if (isDownloading) return; setIsDownloading("docx"); onDownloadStart?.("docx"); try { await downloadMarkdownAsDocx(markdown, filename, options); } catch (error) { onError?.( error instanceof Error ? error : new Error(String(error)), "docx", ); } finally { setIsDownloading(null); onDownloadEnd?.("docx"); } }, [isDownloading, onDownloadStart, onDownloadEnd, onError], ); const downloadAsPdf = useCallback( async ( markdown: string, filename: string, options?: PdfOptions & { resolveAssetUrl?: (rawPath: string) => string | null | Promise; }, ) => { if (isDownloading) return; setIsDownloading("pdf"); onDownloadStart?.("pdf"); try { await downloadMarkdownAsPdf(markdown, filename, options); } catch (error) { onError?.( error instanceof Error ? error : new Error(String(error)), "pdf", ); } finally { setIsDownloading(null); onDownloadEnd?.("pdf"); } }, [isDownloading, onDownloadStart, onDownloadEnd, onError], ); return { isDownloading, downloadAsDocx, downloadAsPdf, canDownload: isDownloading === null, }; } // 导出转换函数,供非 React 环境使用 export { downloadMarkdownAsDocx, downloadMarkdownAsPdf } from "./converter";