78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { createReactBlockSpec } from "@blocknote/react";
|
|
import { RiFileTextFill } from "react-icons/ri";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
const normalizeTitle = (value?: string | null) => {
|
|
if (!value || !value.trim()) {
|
|
return "未命名页面";
|
|
}
|
|
return value;
|
|
};
|
|
|
|
const PageReferenceContent = ({
|
|
pageId,
|
|
title,
|
|
asChildPage,
|
|
}: {
|
|
pageId: string;
|
|
title: string;
|
|
asChildPage: boolean;
|
|
}) => {
|
|
const router = useRouter();
|
|
// 说明:Convex 迁移阶段,直接使用 block props 里的 title,不做实时订阅/拉取。
|
|
// 页面引用的标题会由编辑器同步更新 block.props.title。
|
|
const resolvedTitle = normalizeTitle(title);
|
|
|
|
const navigate = () => {
|
|
if (pageId) {
|
|
router.push(`/documents/${pageId}`);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div
|
|
data-child-page={asChildPage ? "true" : "false"}
|
|
role="button"
|
|
tabIndex={0}
|
|
onClick={navigate}
|
|
onKeyDown={(event) => {
|
|
if ((event.key === "Enter" || event.key === " ") && pageId) {
|
|
event.preventDefault();
|
|
navigate();
|
|
}
|
|
}}
|
|
className="group mt-2 inline-flex items-center gap-1.5 rounded-[3px] px-1.5 py-0.5 text-[#37352F] hover:bg-[rgba(55,53,47,0.08)] transition-colors duration-150"
|
|
style={{ fontFamily: "Inter, system-ui, sans-serif" }}
|
|
>
|
|
<RiFileTextFill className="w-4 h-4 text-[#9B9A97] group-hover:text-[#37352F] transition-colors" aria-hidden />
|
|
<span className="text-[15px] font-medium leading-normal">{resolvedTitle}</span>
|
|
<span className="text-[13px] text-[#9B9A97] opacity-0 group-hover:opacity-100 ml-2">
|
|
→
|
|
</span>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const pageReferenceBlock = createReactBlockSpec(
|
|
{
|
|
type: "pageReference",
|
|
propSchema: {
|
|
pageId: { default: "" },
|
|
title: { default: "未命名页面" },
|
|
asChildPage: { default: false },
|
|
},
|
|
content: "none",
|
|
},
|
|
() => ({
|
|
render: ({ block }) => (
|
|
<PageReferenceContent
|
|
pageId={block.props.pageId}
|
|
title={block.props.title}
|
|
asChildPage={Boolean((block.props as any).asChildPage)}
|
|
/>
|
|
),
|
|
}),
|
|
)();
|