From caacd67165a16f32c340c71098b68590bd895be1 Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 26 Jun 2024 17:49:07 -0400 Subject: [PATCH] feat: add markown editor preview (#29) --- package.json | 2 + src/components/editor/Editor.tsx | 21 ++--------- src/components/editor/EditorControls.tsx | 2 +- src/components/editor/EditorWrapper.tsx | 47 ++++++++++++++++++++++++ src/components/editor/Preview.tsx | 23 ++++++++++++ src/components/editor/TagInput.tsx | 4 +- src/components/notes/NoteCard.tsx | 2 - src/pages/HomePage.tsx | 4 +- src/styles/globals.css | 15 ++++++-- 9 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 src/components/editor/EditorWrapper.tsx create mode 100644 src/components/editor/Preview.tsx diff --git a/package.json b/package.json index 8159b12b..b26d9d0f 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@tauri-apps/plugin-os": "^2.0.0-beta.2", "@tauri-apps/plugin-shell": "^2.0.0-beta.2", "@uiw/codemirror-themes": "^4.21.24", + "@uiw/react-markdown-preview": "^5.1.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "^1.0.0", @@ -50,6 +51,7 @@ "react-hook-form": "^7.52.0", "react-intersection-observer": "^9.8.2", "react-resizable-panels": "^2.0.13", + "rehype-sanitize": "^6.0.0", "react-router-dom": "^6.24.0", "sonner": "^1.4.32", "tailwind-merge": "^2.3.0", diff --git a/src/components/editor/Editor.tsx b/src/components/editor/Editor.tsx index 8e6537a6..e5b5c06d 100644 --- a/src/components/editor/Editor.tsx +++ b/src/components/editor/Editor.tsx @@ -4,9 +4,6 @@ import { useCM6Editor } from "~/hooks/useCM6Editor"; import { useAppContext } from "~/store"; import { type InfiniteQueryData, type Note } from "~/types"; -import EditorControls from "./EditorControls"; -import TagInput from "./TagInput"; - export const Editor = () => { const { currentNote, setCurrentNote, currentTrashedNote } = useAppContext(); @@ -45,20 +42,10 @@ export const Editor = () => { }); return ( - <> - {(currentNote ?? currentTrashedNote) && ( -
-
-
- - -
-
- )} - +
); }; diff --git a/src/components/editor/EditorControls.tsx b/src/components/editor/EditorControls.tsx index 8725adcd..3231e61b 100644 --- a/src/components/editor/EditorControls.tsx +++ b/src/components/editor/EditorControls.tsx @@ -37,7 +37,7 @@ export default function EditorControls() { } return ( -
+
diff --git a/src/components/editor/EditorWrapper.tsx b/src/components/editor/EditorWrapper.tsx new file mode 100644 index 00000000..221281f3 --- /dev/null +++ b/src/components/editor/EditorWrapper.tsx @@ -0,0 +1,47 @@ +import { useState } from "react"; + +import { Button } from "~/components/ui/button"; +import { useAppContext } from "~/store"; +import { Eye } from "lucide-react"; + +import Editor from "./Editor"; +import EditorControls from "./EditorControls"; +import Preview from "./Preview"; +import TagInput from "./TagInput"; + +export const EditorWrapper = () => { + const { currentNote, currentTrashedNote } = useAppContext(); + const [showPreview, setShowPreview] = useState(false); + + return ( + <> + {(currentNote ?? currentTrashedNote) && ( +
+ {!showPreview && } + {showPreview && } +
+ +
+
+ + +
+
+ )} + + ); +}; + +export default EditorWrapper; diff --git a/src/components/editor/Preview.tsx b/src/components/editor/Preview.tsx new file mode 100644 index 00000000..f837fffa --- /dev/null +++ b/src/components/editor/Preview.tsx @@ -0,0 +1,23 @@ +import MarkdownPreview from "@uiw/react-markdown-preview"; +import { useAppContext } from "~/store"; +import rehypeSanitize from "rehype-sanitize"; + +const rehypePlugins = [rehypeSanitize]; + +export const Preview = () => { + const { currentNote, currentTrashedNote } = useAppContext(); + + return ( +
+
+ +
+
+ ); +}; + +export default Preview; diff --git a/src/components/editor/TagInput.tsx b/src/components/editor/TagInput.tsx index 771c3e5b..4622beb0 100644 --- a/src/components/editor/TagInput.tsx +++ b/src/components/editor/TagInput.tsx @@ -25,7 +25,7 @@ export default function TagInput() { if (noteId === undefined) return; - if (currentNote?.tags.some(tag => tag.name === tagName)) return; + if (currentNote?.tags.some((tag) => tag.name === tagName)) return; const getTagResponse = await getTag({ name: tagName }); const existingTag = getTagResponse.data; @@ -68,7 +68,7 @@ export default function TagInput() { }; return ( -
+
{currentNote?.tags?.map((tag, tagIndex) => { return ; diff --git a/src/components/notes/NoteCard.tsx b/src/components/notes/NoteCard.tsx index d3fcb6c6..0c3296de 100644 --- a/src/components/notes/NoteCard.tsx +++ b/src/components/notes/NoteCard.tsx @@ -38,8 +38,6 @@ export default function NoteCard({ note }: Props) { note.tags = currentNoteTags; setCurrentNote(note); - console.log("currentNote", currentNote); - if (activePage === "settings") { setActivePage("editor"); } diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index e8410512..bda47844 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -1,5 +1,5 @@ import ContextSidebar from "~/components/context/ContextSidebar"; -import Editor from "~/components/editor/Editor"; +import EditorWrapper from "~/components/editor/EditorWrapper"; import NoteFeed from "~/components/notes/NoteFeed"; import NoteFeedHeader from "~/components/notes/NoteFeedHeader"; import SearchFeed from "~/components/notes/SearchFeed"; @@ -33,7 +33,7 @@ export default function HomePage() { {activePage === "settings" && } - {activePage === "editor" && } + {activePage === "editor" && }
diff --git a/src/styles/globals.css b/src/styles/globals.css index 44cf26d2..19bd60e4 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -75,15 +75,15 @@ @apply bg-background text-foreground; } - .editor-container .cm-scroller { - overflow: auto; - } - .editor-container .cm-editor { width: 100%; height: 100%; } + .editor-container .cm-scroller { + overflow: auto; + } + .editor-container .cm-content { padding-right: 1rem; padding-left: 1rem; @@ -92,6 +92,13 @@ } } +.wmde-markdown { + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important; + @apply !text-foreground; + @apply !bg-background; +} + /* TODO: fix this so that the shadcn scroll area bar can be used */ /* Scrollbar background */