52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
"use client";
|
|
import { EditorBubble, useEditor } from "novel";
|
|
import { Fragment, useState } from "react";
|
|
import { NodeSelector } from "../selector/node-selector";
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { LinkSelector } from "../selector/link-selector";
|
|
import { TextButtons } from "../selector/text-buttont";
|
|
import { ColorSelector } from "../selector/color-selector";
|
|
|
|
const BubbleMenu = ({
|
|
hideNodeSelector = false,
|
|
}: {
|
|
hideNodeSelector?: boolean;
|
|
}) => {
|
|
const { editor } = useEditor();
|
|
const [openNode, setOpenNode] = useState(false);
|
|
const [openColor, setOpenColor] = useState(false);
|
|
const [openLink, setOpenLink] = useState(false);
|
|
const [open, setOpen] = useState(false);
|
|
|
|
return (
|
|
<EditorBubble
|
|
tippyOptions={{
|
|
placement: open ? "bottom-start" : "top",
|
|
onHidden: () => {
|
|
setOpen(false);
|
|
editor?.chain().unsetHighlight().run();
|
|
},
|
|
}}
|
|
className="flex w-fit max-w-[90vw] overflow-hidden rounded-md border border-muted bg-background shadow-xl"
|
|
>
|
|
{!open && (
|
|
<Fragment>
|
|
{!hideNodeSelector && (
|
|
<>
|
|
<NodeSelector open={openNode} onOpenChange={setOpenNode} />
|
|
<Separator orientation="vertical" />
|
|
</>
|
|
)}
|
|
<LinkSelector open={openLink} onOpenChange={setOpenLink} />
|
|
<Separator orientation="vertical" />
|
|
<TextButtons />
|
|
<Separator orientation="vertical" />
|
|
<ColorSelector open={openColor} onOpenChange={setOpenColor} />
|
|
</Fragment>
|
|
)}
|
|
</EditorBubble>
|
|
);
|
|
};
|
|
|
|
export default BubbleMenu;
|