21 lines
1.9 KiB
TypeScript
21 lines
1.9 KiB
TypeScript
/**
|
|
* 旧版画布未同步草稿的选择对话框。通过原生dialog提供模态展示,把恢复、导出或使用服务端版本交给调用方。
|
|
* 本组件不读取草稿、不写服务端,也不判断本地内容是否能安全覆盖;canRestore由上层计算。
|
|
*/
|
|
"use client";
|
|
import { useEffect, useRef } from "react";
|
|
import { createPortal } from "react-dom";
|
|
import styles from "./canvas.module.css";
|
|
/** 可恢复时显示恢复按钮,否则提示子图关系变化;导出按钮仅在提供exportDraft回调时出现。 */
|
|
export function DraftRecovery({ restore, discard, canRestore = true, exportDraft }: { restore: () => void; discard: () => void; canRestore?: boolean; exportDraft?: () => void }) {
|
|
const dialog = useRef<HTMLDialogElement>(null);
|
|
// 挂载时showModal启用浏览器模态行为,卸载时close;不额外保存一份open状态。
|
|
useEffect(() => { const element = dialog.current; element?.showModal(); return () => element?.close(); }, []);
|
|
// 无document不创建Portal;取消事件阻止默认Escape关闭,要求用户通过明确的版本选择按钮处理。
|
|
if (typeof document === "undefined") return null;
|
|
return createPortal(<dialog ref={dialog} className={styles.recoveryDialog} aria-labelledby="draft-recovery-title" onCancel={(event) => event.preventDefault()}>
|
|
<h2 id="draft-recovery-title">发现未同步的本地草稿</h2><p>{canRestore ? "服务端画布已读取。恢复草稿会以本地内容替换当前服务端版本,请选择要继续编辑的版本。" : "画布的子图关系已更新,这份旧草稿不能直接覆盖。可以先导出草稿,再使用服务端版本继续编辑。"}</p>
|
|
<div>{canRestore && <button type="button" onClick={restore}>恢复本地草稿</button>}{exportDraft && <button type="button" onClick={exportDraft}>导出本地草稿</button>}<button type="button" onClick={discard}>使用服务端版本</button></div>
|
|
</dialog>, document.body);
|
|
}
|