fix: wrap rich input toolbar, closes #1588

This commit is contained in:
Amruth Pillai
2023-11-26 15:26:39 +01:00
parent bf9cd2b248
commit 9298a7473e
2 changed files with 273 additions and 291 deletions

View File

@ -41,8 +41,8 @@ export const BuilderLayout = () => {
<PanelGroup direction="horizontal"> <PanelGroup direction="horizontal">
<Panel <Panel
minSizePixels={48} minSizePixels={48}
maxSizePercentage={35} maxSizePercentage={45}
defaultSizePercentage={28} defaultSizePercentage={30}
onResize={({ sizePercentage }) => leftSetSize(sizePercentage)} onResize={({ sizePercentage }) => leftSetSize(sizePercentage)}
className={cn("z-10 bg-background", !leftHandle.isDragging && "transition-[flex]")} className={cn("z-10 bg-background", !leftHandle.isDragging && "transition-[flex]")}
> >
@ -61,8 +61,8 @@ export const BuilderLayout = () => {
/> />
<Panel <Panel
minSizePixels={48} minSizePixels={48}
maxSizePercentage={35} maxSizePercentage={45}
defaultSizePercentage={28} defaultSizePercentage={30}
onResize={({ sizePercentage }) => rightSetSize(sizePercentage)} onResize={({ sizePercentage }) => rightSetSize(sizePercentage)}
className={cn("z-10 bg-background", !rightHandle.isDragging && "transition-[flex]")} className={cn("z-10 bg-background", !rightHandle.isDragging && "transition-[flex]")}
> >

View File

@ -43,8 +43,6 @@ import { Button } from "./button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "./form"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "./form";
import { Input } from "./input"; import { Input } from "./input";
import { Popover, PopoverContent } from "./popover"; import { Popover, PopoverContent } from "./popover";
import { ScrollArea } from "./scroll-area";
import { Separator } from "./separator";
import { Skeleton } from "./skeleton"; import { Skeleton } from "./skeleton";
import { Toggle } from "./toggle"; import { Toggle } from "./toggle";
import { Tooltip } from "./tooltip"; import { Tooltip } from "./tooltip";
@ -137,299 +135,283 @@ const Toolbar = ({ editor }: { editor: Editor }) => {
}, [editor]); }, [editor]);
return ( return (
<div className="absolute inset-x-0 top-2 px-2"> <div className="flex flex-wrap gap-0.5 border p-1">
<ScrollArea orientation="horizontal"> <Tooltip content="Bold">
<div className="flex h-8 gap-1"> <Toggle
<Tooltip content="Bold"> size="sm"
<Toggle pressed={editor.isActive("bold")}
size="sm" disabled={!editor.can().chain().focus().toggleBold().run()}
pressed={editor.isActive("bold")} onPressedChange={() => editor.chain().focus().toggleBold().run()}
disabled={!editor.can().chain().focus().toggleBold().run()} >
onPressedChange={() => editor.chain().focus().toggleBold().run()} <TextB />
> </Toggle>
<TextB /> </Tooltip>
</Toggle>
</Tooltip>
<Tooltip content="Italic"> <Tooltip content="Italic">
<Toggle <Toggle
size="sm" size="sm"
pressed={editor.isActive("italic")} pressed={editor.isActive("italic")}
disabled={!editor.can().chain().focus().toggleItalic().run()} disabled={!editor.can().chain().focus().toggleItalic().run()}
onPressedChange={() => editor.chain().focus().toggleItalic().run()} onPressedChange={() => editor.chain().focus().toggleItalic().run()}
> >
<TextItalic /> <TextItalic />
</Toggle> </Toggle>
</Tooltip> </Tooltip>
<Tooltip content="Strikethrough"> <Tooltip content="Strikethrough">
<Toggle <Toggle
size="sm" size="sm"
pressed={editor.isActive("strike")} pressed={editor.isActive("strike")}
disabled={!editor.can().chain().focus().toggleStrike().run()} disabled={!editor.can().chain().focus().toggleStrike().run()}
onPressedChange={() => editor.chain().focus().toggleStrike().run()} onPressedChange={() => editor.chain().focus().toggleStrike().run()}
> >
<TextStrikethrough /> <TextStrikethrough />
</Toggle> </Toggle>
</Tooltip> </Tooltip>
<Tooltip content="Underline"> <Tooltip content="Underline">
<Toggle <Toggle
size="sm" size="sm"
pressed={editor.isActive("underline")} pressed={editor.isActive("underline")}
disabled={!editor.can().chain().focus().toggleUnderline().run()} disabled={!editor.can().chain().focus().toggleUnderline().run()}
onPressedChange={() => editor.chain().focus().toggleUnderline().run()} onPressedChange={() => editor.chain().focus().toggleUnderline().run()}
> >
<TextAUnderline /> <TextAUnderline />
</Toggle> </Toggle>
</Tooltip> </Tooltip>
<Tooltip content="Highlight"> <Tooltip content="Highlight">
<Toggle <Toggle
size="sm" size="sm"
pressed={editor.isActive("highlight")} pressed={editor.isActive("highlight")}
disabled={!editor.can().chain().focus().toggleHighlight().run()} disabled={!editor.can().chain().focus().toggleHighlight().run()}
onPressedChange={() => editor.chain().focus().toggleHighlight().run()} onPressedChange={() => editor.chain().focus().toggleHighlight().run()}
> >
<HighlighterCircle /> <HighlighterCircle />
</Toggle> </Toggle>
</Tooltip> </Tooltip>
<Tooltip content="Hyperlink"> <Tooltip content="Hyperlink">
<Button type="button" size="sm" variant="ghost" className="px-2" onClick={setLink}> <Button type="button" size="sm" variant="ghost" className="px-2" onClick={setLink}>
<LinkSimple /> <LinkSimple />
</Button>
</Tooltip>
<Tooltip content="Inline Code">
<Toggle
size="sm"
pressed={editor.isActive("code")}
disabled={!editor.can().chain().focus().toggleCode().run()}
onPressedChange={() => editor.chain().focus().toggleCode().run()}
>
<Code />
</Toggle>
</Tooltip>
<Tooltip content="Code Block">
<Toggle
size="sm"
pressed={editor.isActive("codeBlock")}
disabled={!editor.can().chain().focus().toggleCodeBlock().run()}
onPressedChange={() => editor.chain().focus().toggleCodeBlock().run()}
>
<CodeBlock />
</Toggle>
</Tooltip>
<Tooltip content="Heading 1">
<Toggle
size="sm"
pressed={editor.isActive("heading", { level: 1 })}
disabled={!editor.can().chain().focus().toggleHeading({ level: 1 }).run()}
onPressedChange={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
>
<TextHOne />
</Toggle>
</Tooltip>
<Tooltip content="Heading 2">
<Toggle
size="sm"
pressed={editor.isActive("heading", { level: 2 })}
disabled={!editor.can().chain().focus().toggleHeading({ level: 2 }).run()}
onPressedChange={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
>
<TextHTwo />
</Toggle>
</Tooltip>
<Tooltip content="Heading 3">
<Toggle
size="sm"
pressed={editor.isActive("heading", { level: 3 })}
disabled={!editor.can().chain().focus().toggleHeading({ level: 3 }).run()}
onPressedChange={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
>
<TextHThree />
</Toggle>
</Tooltip>
<Tooltip content="Paragraph">
<Toggle
size="sm"
pressed={editor.isActive("paragraph")}
onPressedChange={() => editor.chain().focus().setParagraph().run()}
>
<Paragraph />
</Toggle>
</Tooltip>
<Tooltip content="Align Left">
<Toggle
size="sm"
pressed={editor.isActive({ textAlign: "left" })}
disabled={!editor.can().chain().focus().setTextAlign("left").run()}
onPressedChange={() => editor.chain().focus().setTextAlign("left").run()}
>
<TextAlignLeft />
</Toggle>
</Tooltip>
<Tooltip content="Align Center">
<Toggle
size="sm"
pressed={editor.isActive({ textAlign: "center" })}
disabled={!editor.can().chain().focus().setTextAlign("center").run()}
onPressedChange={() => editor.chain().focus().setTextAlign("center").run()}
>
<TextAlignCenter />
</Toggle>
</Tooltip>
<Tooltip content="Align Right">
<Toggle
size="sm"
pressed={editor.isActive({ textAlign: "right" })}
disabled={!editor.can().chain().focus().setTextAlign("right").run()}
onPressedChange={() => editor.chain().focus().setTextAlign("right").run()}
>
<TextAlignRight />
</Toggle>
</Tooltip>
<Tooltip content="Align Justify">
<Toggle
size="sm"
pressed={editor.isActive({ textAlign: "justify" })}
disabled={!editor.can().chain().focus().setTextAlign("justify").run()}
onPressedChange={() => editor.chain().focus().setTextAlign("justify").run()}
>
<TextAlignJustify />
</Toggle>
</Tooltip>
<Tooltip content="Bullet List">
<Toggle
size="sm"
pressed={editor.isActive("bulletList")}
disabled={!editor.can().chain().focus().toggleBulletList().run()}
onPressedChange={() => editor.chain().focus().toggleBulletList().run()}
>
<ListBullets />
</Toggle>
</Tooltip>
<Tooltip content="Numbered List">
<Toggle
size="sm"
pressed={editor.isActive("orderedList")}
disabled={!editor.can().chain().focus().toggleOrderedList().run()}
onPressedChange={() => editor.chain().focus().toggleOrderedList().run()}
>
<ListNumbers />
</Toggle>
</Tooltip>
<Tooltip content="Outdent">
<Button
size="sm"
variant="ghost"
className="px-2"
onClick={() => editor.chain().focus().liftListItem("listItem").run()}
disabled={!editor.can().chain().focus().liftListItem("listItem").run()}
>
<TextOutdent />
</Button>
</Tooltip>
<Tooltip content="Indent">
<Button
size="sm"
variant="ghost"
className="px-2"
onClick={() => editor.chain().focus().sinkListItem("listItem").run()}
disabled={!editor.can().chain().focus().sinkListItem("listItem").run()}
>
<TextIndent />
</Button>
</Tooltip>
<Popover>
<Tooltip content="Insert Image">
<PopoverTrigger asChild>
<Button size="sm" variant="ghost" className="px-2">
<ImageIcon />
</Button> </Button>
</Tooltip> </PopoverTrigger>
</Tooltip>
<PopoverContent className="w-80">
<InsertImageForm onInsert={(props) => editor.chain().focus().setImage(props).run()} />
</PopoverContent>
</Popover>
<Separator orientation="vertical" className="mx-1" /> <Tooltip content="Insert Break Line">
<Button
size="sm"
variant="ghost"
className="px-2"
onClick={() => editor.chain().focus().setHardBreak().run()}
disabled={!editor.can().chain().focus().setHardBreak().run()}
>
<KeyReturn />
</Button>
</Tooltip>
<Tooltip content="Inline Code"> <Tooltip content="Insert Horizontal Rule">
<Toggle <Button
size="sm" size="sm"
pressed={editor.isActive("code")} variant="ghost"
disabled={!editor.can().chain().focus().toggleCode().run()} className="px-2"
onPressedChange={() => editor.chain().focus().toggleCode().run()} onClick={() => editor.chain().focus().setHorizontalRule().run()}
> disabled={!editor.can().chain().focus().setHorizontalRule().run()}
<Code /> >
</Toggle> <Minus />
</Tooltip> </Button>
</Tooltip>
<Tooltip content="Code Block"> <Tooltip content="Undo">
<Toggle <Button
size="sm" size="sm"
pressed={editor.isActive("codeBlock")} variant="ghost"
disabled={!editor.can().chain().focus().toggleCodeBlock().run()} className="px-2"
onPressedChange={() => editor.chain().focus().toggleCodeBlock().run()} disabled={!editor.can().undo()}
> onClick={() => editor.chain().focus().undo().run()}
<CodeBlock /> >
</Toggle> <ArrowCounterClockwise />
</Tooltip> </Button>
</Tooltip>
<Separator orientation="vertical" className="mx-1" /> <Tooltip content="Redo">
<Button
<Tooltip content="Heading 1"> size="sm"
<Toggle variant="ghost"
size="sm" className="px-2"
pressed={editor.isActive("heading", { level: 1 })} disabled={!editor.can().redo()}
disabled={!editor.can().chain().focus().toggleHeading({ level: 1 }).run()} onClick={() => editor.chain().focus().redo().run()}
onPressedChange={() => editor.chain().focus().toggleHeading({ level: 1 }).run()} >
> <ArrowClockwise />
<TextHOne /> </Button>
</Toggle> </Tooltip>
</Tooltip>
<Tooltip content="Heading 2">
<Toggle
size="sm"
pressed={editor.isActive("heading", { level: 2 })}
disabled={!editor.can().chain().focus().toggleHeading({ level: 2 }).run()}
onPressedChange={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
>
<TextHTwo />
</Toggle>
</Tooltip>
<Tooltip content="Heading 3">
<Toggle
size="sm"
pressed={editor.isActive("heading", { level: 3 })}
disabled={!editor.can().chain().focus().toggleHeading({ level: 3 }).run()}
onPressedChange={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
>
<TextHThree />
</Toggle>
</Tooltip>
<Tooltip content="Paragraph">
<Toggle
size="sm"
pressed={editor.isActive("paragraph")}
onPressedChange={() => editor.chain().focus().setParagraph().run()}
>
<Paragraph />
</Toggle>
</Tooltip>
<Separator orientation="vertical" className="mx-1" />
<Tooltip content="Align Left">
<Toggle
size="sm"
pressed={editor.isActive({ textAlign: "left" })}
disabled={!editor.can().chain().focus().setTextAlign("left").run()}
onPressedChange={() => editor.chain().focus().setTextAlign("left").run()}
>
<TextAlignLeft />
</Toggle>
</Tooltip>
<Tooltip content="Align Center">
<Toggle
size="sm"
pressed={editor.isActive({ textAlign: "center" })}
disabled={!editor.can().chain().focus().setTextAlign("center").run()}
onPressedChange={() => editor.chain().focus().setTextAlign("center").run()}
>
<TextAlignCenter />
</Toggle>
</Tooltip>
<Tooltip content="Align Right">
<Toggle
size="sm"
pressed={editor.isActive({ textAlign: "right" })}
disabled={!editor.can().chain().focus().setTextAlign("right").run()}
onPressedChange={() => editor.chain().focus().setTextAlign("right").run()}
>
<TextAlignRight />
</Toggle>
</Tooltip>
<Tooltip content="Align Justify">
<Toggle
size="sm"
pressed={editor.isActive({ textAlign: "justify" })}
disabled={!editor.can().chain().focus().setTextAlign("justify").run()}
onPressedChange={() => editor.chain().focus().setTextAlign("justify").run()}
>
<TextAlignJustify />
</Toggle>
</Tooltip>
<Separator orientation="vertical" className="mx-1" />
<Tooltip content="Bullet List">
<Toggle
size="sm"
pressed={editor.isActive("bulletList")}
disabled={!editor.can().chain().focus().toggleBulletList().run()}
onPressedChange={() => editor.chain().focus().toggleBulletList().run()}
>
<ListBullets />
</Toggle>
</Tooltip>
<Tooltip content="Numbered List">
<Toggle
size="sm"
pressed={editor.isActive("orderedList")}
disabled={!editor.can().chain().focus().toggleOrderedList().run()}
onPressedChange={() => editor.chain().focus().toggleOrderedList().run()}
>
<ListNumbers />
</Toggle>
</Tooltip>
<Tooltip content="Outdent">
<Button
size="sm"
variant="ghost"
className="px-2"
onClick={() => editor.chain().focus().liftListItem("listItem").run()}
disabled={!editor.can().chain().focus().liftListItem("listItem").run()}
>
<TextOutdent />
</Button>
</Tooltip>
<Tooltip content="Indent">
<Button
size="sm"
variant="ghost"
className="px-2"
onClick={() => editor.chain().focus().sinkListItem("listItem").run()}
disabled={!editor.can().chain().focus().sinkListItem("listItem").run()}
>
<TextIndent />
</Button>
</Tooltip>
<Separator orientation="vertical" className="mx-1" />
<Popover>
<PopoverTrigger asChild>
<Button size="sm" variant="ghost" className="px-2">
<ImageIcon />
</Button>
</PopoverTrigger>
<PopoverContent className="w-80">
<InsertImageForm onInsert={(props) => editor.chain().focus().setImage(props).run()} />
</PopoverContent>
</Popover>
<Tooltip content="Insert Break Line">
<Button
size="sm"
variant="ghost"
className="px-2"
onClick={() => editor.chain().focus().setHardBreak().run()}
disabled={!editor.can().chain().focus().setHardBreak().run()}
>
<KeyReturn />
</Button>
</Tooltip>
<Tooltip content="Insert Horizontal Rule">
<Button
size="sm"
variant="ghost"
className="px-2"
onClick={() => editor.chain().focus().setHorizontalRule().run()}
disabled={!editor.can().chain().focus().setHorizontalRule().run()}
>
<Minus />
</Button>
</Tooltip>
<Separator orientation="vertical" className="mx-1" />
<Tooltip content="Undo">
<Button
size="sm"
variant="ghost"
className="px-2"
disabled={!editor.can().undo()}
onClick={() => editor.chain().focus().undo().run()}
>
<ArrowCounterClockwise />
</Button>
</Tooltip>
<Tooltip content="Redo">
<Button
size="sm"
variant="ghost"
className="px-2"
disabled={!editor.can().redo()}
onClick={() => editor.chain().focus().redo().run()}
>
<ArrowClockwise />
</Button>
</Tooltip>
</div>
</ScrollArea>
<Separator className="mt-2" />
</div> </div>
); );
}; };
@ -484,13 +466,13 @@ export const RichInput = forwardRef<Editor, RichInputProps>(
} }
return ( return (
<div className="relative"> <div>
{!hideToolbar && <Toolbar editor={editor} />} {!hideToolbar && <Toolbar editor={editor} />}
<EditorContent <EditorContent
editor={editor} editor={editor}
className={cn( className={cn(
"grid min-h-[160px] w-full rounded-sm border bg-transparent px-3 pb-2 pt-14 text-sm placeholder:opacity-80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50", "grid min-h-[160px] w-full rounded-sm border bg-transparent px-3 py-2 text-sm placeholder:opacity-80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50",
hideToolbar && "pt-2", hideToolbar && "pt-2",
className, className,
)} )}