51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
"use client";
|
||
|
||
import { createReactBlockSpec } from "@blocknote/react";
|
||
|
||
export const progressBlock = createReactBlockSpec(
|
||
{
|
||
type: "progressMeter",
|
||
propSchema: {
|
||
percent: { default: 0, type: "number" },
|
||
auto: { default: true, type: "boolean" },
|
||
summary: { default: "", type: "string" },
|
||
},
|
||
content: "inline",
|
||
},
|
||
{
|
||
render: ({ block, editor }) => {
|
||
const percent = block.props.percent ?? 0;
|
||
const handleToggle = () => {
|
||
editor.updateBlock(block, { props: { auto: !block.props.auto } });
|
||
};
|
||
|
||
const handleBarClick = () => {
|
||
if (block.props.auto) return;
|
||
const input = window.prompt("设置进度(0-100)", percent.toString());
|
||
if (!input) return;
|
||
const value = Number.parseInt(input, 10);
|
||
if (Number.isNaN(value)) return;
|
||
editor.updateBlock(block, {
|
||
props: { percent: Math.min(100, Math.max(0, value)) },
|
||
});
|
||
};
|
||
|
||
return (
|
||
<div className="wolai-progress">
|
||
<div className="wolai-progress__header">
|
||
<span className="wolai-progress__summary">{block.props.summary || "暂无条目"}</span>
|
||
<button type="button" className="wolai-progress__mode" onClick={handleToggle}>
|
||
{block.props.auto ? "自动" : "手动"}
|
||
</button>
|
||
</div>
|
||
<div className="wolai-progress__bar" onClick={handleBarClick}>
|
||
<div className="wolai-progress__fill" style={{ width: `${percent}%` }} />
|
||
</div>
|
||
<span className="wolai-progress__percent">{percent}%</span>
|
||
<div className="wolai-progress__description" />
|
||
</div>
|
||
);
|
||
},
|
||
},
|
||
)();
|