Skip to content

Commit

Permalink
refactor: consolidate rich text editor and viewer configurations thro…
Browse files Browse the repository at this point in the history
…ugh plugins and default styles
  • Loading branch information
typeWolffo committed Jan 24, 2025
1 parent 3a1ccab commit 6fa789f
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 46 deletions.
29 changes: 11 additions & 18 deletions apps/web/app/components/RichText/Editor.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { TaskItem } from "@tiptap/extension-task-item";
import { TaskList } from "@tiptap/extension-task-list";
import { EditorContent, useEditor } from "@tiptap/react";
// eslint-disable-next-line import/no-named-as-default
import StarterKit from "@tiptap/starter-kit";

import { cn } from "~/lib/utils";

import { plugins } from "./plugins";
import { defaultClasses } from "./styles";
import EditorToolbar from "./toolbar/EditorToolbar";

type EditorProps = {
Expand All @@ -18,19 +16,7 @@ type EditorProps = {

const Editor = ({ content, placeholder, onChange, id, className }: EditorProps) => {
const editor = useEditor({
extensions: [
StarterKit,
TaskList,
TaskItem.configure({
nested: true,
HTMLAttributes: {
class: "flex items-start gap-2 [&_p]:inline [&_p]:m-0",
},
onReadOnlyChecked: (_node, _checked) => {
return true;
},
}),
],
extensions: [...plugins],
content: content,
onUpdate: ({ editor }) => {
onChange(editor.getHTML());
Expand All @@ -44,6 +30,8 @@ const Editor = ({ content, placeholder, onChange, id, className }: EditorProps)

if (!editor) return <></>;

const editorClasses = cn("h-full", defaultClasses.ul, defaultClasses.ol, defaultClasses.taskList);

return (
<div className="prose w-full max-w-none overflow-hidden rounded-lg border border-neutral-300 bg-background dark:prose-invert [&_.ProseMirror]:leading-tight">
<EditorToolbar editor={editor} />
Expand All @@ -53,7 +41,12 @@ const Editor = ({ content, placeholder, onChange, id, className }: EditorProps)
className,
)}
>
<EditorContent id={id} editor={editor} placeholder={placeholder} className="h-full" />
<EditorContent
id={id}
editor={editor}
placeholder={placeholder}
className={editorClasses}
/>
</div>
</div>
);
Expand Down
29 changes: 4 additions & 25 deletions apps/web/app/components/RichText/Viever.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
import { TaskItem } from "@tiptap/extension-task-item";
import { TaskList } from "@tiptap/extension-task-list";
import { EditorContent, useEditor } from "@tiptap/react";
// eslint-disable-next-line import/no-named-as-default
import StarterKit from "@tiptap/starter-kit";

import { cn } from "~/lib/utils";

import { plugins } from "./plugins";
import { defaultClasses } from "./styles";

type ViewerProps = {
content: string;
style?: "default" | "prose";
className?: string;
variant?: "default" | "lesson";
};

const defaultClasses = {
ul: "[&>div>ul]:list-disc [&>div>ul]:list-inside [&>div>ul>li>p]:inline [&_ul]:list-disc [&_ul]:ml-6 [&_ul>li>p]:inline",
ol: "[&>div>ol]:list-decimal [&>div>ol]:list-inside [&>div>ol>li>p]:inline",
taskList: "[&_[data-type='taskList']]:list-none [&_[data-type='taskList']]:pl-0",
};

const lessonVariantClasses = {
layout: "[&>div]:flex [&>div]:flex-col [&>div]:gap-y-6",
h2: "[&>div>h2]:h6 [&>div>h2]:text-neutral-950",
Expand All @@ -29,21 +22,7 @@ const lessonVariantClasses = {

const Viewer = ({ content, style, className, variant = "default" }: ViewerProps) => {
const editor = useEditor({
extensions: [
StarterKit,
TaskList.configure({
HTMLAttributes: {
class: "list-none",
},
}),
TaskItem.configure({
nested: true,
HTMLAttributes: {
class: "flex items-start gap-2",
},
onReadOnlyChecked: (_node, _checked) => true,
}),
],
extensions: [...plugins],
content: content,
editable: false,
});
Expand Down
19 changes: 19 additions & 0 deletions apps/web/app/components/RichText/plugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { TaskItem } from "@tiptap/extension-task-item";
import { TaskList } from "@tiptap/extension-task-list";
import { StarterKit } from "@tiptap/starter-kit";

export const plugins = [
StarterKit,
TaskList.configure({
HTMLAttributes: {
class: "list-none",
},
}),
TaskItem.configure({
nested: true,
HTMLAttributes: {
class: "flex items-start gap-2 [&_p]:inline [&_p]:m-0",
},
onReadOnlyChecked: (_node, _checked) => true,
}),
];
25 changes: 25 additions & 0 deletions apps/web/app/components/RichText/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const defaultClasses = {
ul: `
[&>div>ul]:list-disc
[&>div>ul]:pl-5
[&>div>ul>li>p]:inline
[&>div>ul>li>p]:text-neutral-900
[&_ul]:list-disc
[&_[contenteditable='true']>ul>li]:pl-0
[&_[contenteditable='true']>ul>li_ul_li]:pl-0
[&_[contenteditable='false']>ul>li]:pl-4
[&_[contenteditable='false']>ul>li_ul_li]:pl-4
[&_ul>li]:marker:text-neutral-400
[&_ul>li>p]:inline
[&_ul>li>p]:text-neutral-900
`,
ol: `
[&>div>ol]:list-decimal
[&>div>ol]:list-inside
[&>div>ol>li>p]:inline
[&>div>ol>li>ol]:pl-4
[&_ol>li>ol]:pl-4
`,
taskList: "[&_[data-type='taskList']]:list-none [&_[data-type='taskList']]:pl-0",
};
8 changes: 5 additions & 3 deletions apps/web/app/components/RichText/toolbar/EditorToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { Button } from "~/components/ui/button";
import { ToggleGroup, Toolbar } from "~/components/ui/toolbar";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "~/components/ui/tooltip";
import { cn } from "~/lib/utils";

import { FormatType } from "./FormatType";

Expand Down Expand Up @@ -141,9 +142,10 @@ const EditorToolbar = ({ editor }: EditorToolbarProps) => {
<TooltipTrigger>
<Button
size="sm"
className={`bg-transparent text-black ${
editor.isActive("taskList") ? "bg-blue-100" : "hover:bg-blue-100"
}`}
className={cn("bg-transparent text-black", {
"bg-blue-100": editor.isActive("taskList"),
"hover:bg-blue-100": !editor.isActive("taskList"),
})}
onClick={handleToggle(() => editor.chain().focus().toggleTaskList().run())}
>
<CheckSquare className="h-4 w-4" />
Expand Down

0 comments on commit 6fa789f

Please sign in to comment.