feat: add novel editor

This commit is contained in:
Jiang Feng
2025-04-26 00:20:49 +08:00
parent 26c2679b1a
commit ba8c5fbcd3
22 changed files with 3760 additions and 5 deletions

View File

@@ -0,0 +1,81 @@
import {
ArrowDownWideNarrow,
CheckCheck,
RefreshCcwDot,
StepForward,
WrapText,
} from "lucide-react";
import { getPrevText, useEditor } from "novel";
import { CommandGroup, CommandItem, CommandSeparator } from "../../ui/command";
const options = [
{
value: "improve",
label: "Improve writing",
icon: RefreshCcwDot,
},
{
value: "fix",
label: "Fix grammar",
icon: CheckCheck,
},
{
value: "shorter",
label: "Make shorter",
icon: ArrowDownWideNarrow,
},
{
value: "longer",
label: "Make longer",
icon: WrapText,
},
];
interface AISelectorCommandsProps {
onSelect: (value: string, option: string) => void;
}
const AISelectorCommands = ({ onSelect }: AISelectorCommandsProps) => {
const { editor } = useEditor();
if (!editor) return null;
return (
<>
<CommandGroup heading="Edit or review selection">
{options.map((option) => (
<CommandItem
onSelect={(value) => {
const slice = editor.state.selection.content();
const text = editor.storage.markdown.serializer.serialize(
slice.content,
);
onSelect(text, value);
}}
className="flex gap-2 px-4"
key={option.value}
value={option.value}
>
<option.icon className="h-4 w-4 text-purple-500" />
{option.label}
</CommandItem>
))}
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Use AI to do more">
<CommandItem
onSelect={() => {
const pos = editor.state.selection.from;
const text = getPrevText(editor, pos);
onSelect(text, "continue");
}}
value="continue"
className="gap-2 px-4"
>
<StepForward className="h-4 w-4 text-purple-500" />
Continue writing
</CommandItem>
</CommandGroup>
</>
);
};
export default AISelectorCommands;