Make rich editor full height

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-03-18 12:50:36 +04:00
parent b84eab4698
commit eede0b72f1
4 changed files with 25 additions and 21 deletions

View File

@@ -150,7 +150,7 @@ export function DocumentLayout(props: { queryRef: PreloadedQuery<DocumentLayoutQ
return ( return (
<> <>
<div className="space-y-6"> <div className="flex flex-col gap-6 h-full">
<div className="flex justify-between items-center mb-4"> <div className="flex justify-between items-center mb-4">
<Breadcrumb <Breadcrumb
items={[ items={[

View File

@@ -117,13 +117,11 @@ export function DocumentDescriptionPage(props: { queryRef: PreloadedQuery<Docume
); );
return ( return (
<div> <RichEditor
<RichEditor className="flex-1"
content={currentVersion.content} content={currentVersion.content}
disabled={currentVersion.status !== "DRAFT"} disabled={currentVersion.status !== "DRAFT"}
onChange={handleUpdate} onChangeContent={handleUpdate}
/> />
{/* <Markdown content={currentVersion.content} /> */}
</div>
); );
} }

View File

@@ -81,11 +81,11 @@ export function Layout({
{sidebar && <Sidebar>{sidebar}</Sidebar>} {sidebar && <Sidebar>{sidebar}</Sidebar>}
<main <main
className={clsx( className={clsx(
"overflow-y-auto w-full mt-12 transition-all duration-300", "overflow-y-auto w-full mt-12 transition-all duration-300 h-[calc(100vh-48px)]",
hasDrawer && "pr-105", hasDrawer && "pr-105",
)} )}
> >
<div className="py-12 px-8 max-w-[1200px] w-full mx-auto"> <div className="py-12 px-8 max-w-[1200px] w-full mx-auto h-full">
{children} {children}
</div> </div>
</main> </main>

View File

@@ -16,7 +16,7 @@ import { Underline } from "@tiptap/extension-underline";
import { Dropcursor, Gapcursor, UndoRedo } from "@tiptap/extensions"; import { Dropcursor, Gapcursor, UndoRedo } from "@tiptap/extensions";
import { type Content, EditorContent, useEditor, useEditorState } from "@tiptap/react"; import { type Content, EditorContent, useEditor, useEditorState } from "@tiptap/react";
import { BubbleMenu, FloatingMenu } from "@tiptap/react/menus"; import { BubbleMenu, FloatingMenu } from "@tiptap/react/menus";
import { useEffect } from "react"; import { type ComponentProps, useEffect } from "react";
import { tv } from "tailwind-variants"; import { tv } from "tailwind-variants";
const extensions = [ const extensions = [
@@ -47,6 +47,7 @@ const richEditorVariants = tv({
bubbleMenu: ["flex items-center gap-1 rounded-lg border border-border-mid bg-level-0 p-1 shadow-md"], bubbleMenu: ["flex items-center gap-1 rounded-lg border border-border-mid bg-level-0 p-1 shadow-md"],
floatingMenu: ["flex items-center gap-1 rounded-lg border border-border-mid bg-level-0 p-1 shadow-md"], floatingMenu: ["flex items-center gap-1 rounded-lg border border-border-mid bg-level-0 p-1 shadow-md"],
menuButton: ["px-2 py-1 text-sm rounded-sm font-semibold bg-level-0 hover:bg-subtle"], menuButton: ["px-2 py-1 text-sm rounded-sm font-semibold bg-level-0 hover:bg-subtle"],
editor: ["h-full"],
}, },
variants: { variants: {
active: { active: {
@@ -57,7 +58,7 @@ const richEditorVariants = tv({
}, },
}); });
const { bubbleMenu, floatingMenu, menuButton } = richEditorVariants(); const { bubbleMenu, floatingMenu, editor: editorVariants, menuButton } = richEditorVariants();
type MenuButtonProps = { type MenuButtonProps = {
label: string; label: string;
@@ -77,16 +78,21 @@ function MenuButton({ label, active, onClick }: MenuButtonProps) {
); );
} }
interface RichEditorProps { type RichEditorProps = ComponentProps<"div"> & {
content: string; content: string;
disabled?: boolean; disabled?: boolean;
onChange: (content: string) => void; onChangeContent: (content: string) => void;
} };
export function RichEditor(props: RichEditorProps) { export function RichEditor(props: RichEditorProps) {
const { content, disabled = false, onChange } = props; const { className, content, disabled = false, onChangeContent } = props;
const editor = useEditor({ const editor = useEditor({
editorProps: {
attributes: {
class: "h-full",
},
},
editable: !disabled, editable: !disabled,
extensions, extensions,
content: (content ? JSON.parse(content) : "") as Content, content: (content ? JSON.parse(content) : "") as Content,
@@ -101,12 +107,12 @@ export function RichEditor(props: RichEditorProps) {
useEffect(() => { useEffect(() => {
if (watchedContent !== content) { if (watchedContent !== content) {
onChange(watchedContent); onChangeContent(watchedContent);
} }
}, [content, watchedContent, onChange]); }, [content, watchedContent, onChangeContent]);
return ( return (
<div> <div className={editorVariants({ className })}>
<BubbleMenu <BubbleMenu
editor={editor} editor={editor}
className={bubbleMenu()} className={bubbleMenu()}
@@ -200,7 +206,7 @@ export function RichEditor(props: RichEditorProps) {
/> />
</FloatingMenu> </FloatingMenu>
<EditorContent editor={editor} /> <EditorContent className={editorVariants()} editor={editor} />
</div> </div>
); );
} }