highlight markdown in editor
This commit is contained in:
parent
69355707a7
commit
fea7bbf09c
|
|
@ -1,9 +1,26 @@
|
|||
import { useEffect, useRef, useState } from "react"
|
||||
import { EditorState } from "@codemirror/state"
|
||||
import { EditorView, keymap, ViewUpdate } from "@codemirror/view"
|
||||
import { indentWithTab } from "@codemirror/commands"
|
||||
import {
|
||||
EditorView,
|
||||
keymap,
|
||||
type ViewUpdate,
|
||||
dropCursor,
|
||||
drawSelection,
|
||||
crosshairCursor,
|
||||
placeholder as placeholderExtension,
|
||||
} from "@codemirror/view"
|
||||
import {
|
||||
history,
|
||||
defaultKeymap,
|
||||
historyKeymap,
|
||||
indentWithTab,
|
||||
} from "@codemirror/commands"
|
||||
import { markdown } from "@codemirror/lang-markdown"
|
||||
import { history } from "@codemirror/history"
|
||||
import {
|
||||
defaultHighlightStyle,
|
||||
indentOnInput,
|
||||
syntaxHighlighting,
|
||||
} from "@codemirror/language"
|
||||
|
||||
const theme = EditorView.theme({
|
||||
".cm-scroller": {
|
||||
|
|
@ -22,7 +39,8 @@ const theme = EditorView.theme({
|
|||
export const Editor: React.FC<{
|
||||
value: string
|
||||
onChange: (value: string) => void
|
||||
}> = ({ value, onChange }) => {
|
||||
placeholder?: string
|
||||
}> = ({ value, onChange, placeholder }) => {
|
||||
const editorRef = useRef<HTMLDivElement | null>(null)
|
||||
const [view, setView] = useState<EditorView | null>(null)
|
||||
|
||||
|
|
@ -37,13 +55,20 @@ export const Editor: React.FC<{
|
|||
|
||||
const view = new EditorView({
|
||||
state: EditorState.create({
|
||||
doc: value,
|
||||
doc: "",
|
||||
extensions: [
|
||||
keymap.of([indentWithTab]),
|
||||
markdown(),
|
||||
keymap.of([indentWithTab, ...defaultKeymap, ...historyKeymap]),
|
||||
history(),
|
||||
dropCursor(),
|
||||
drawSelection(),
|
||||
indentOnInput(),
|
||||
crosshairCursor(),
|
||||
EditorState.allowMultipleSelections.of(true),
|
||||
updateListener,
|
||||
EditorView.lineWrapping,
|
||||
markdown(),
|
||||
placeholderExtension(placeholder || ""),
|
||||
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
|
||||
theme,
|
||||
],
|
||||
}),
|
||||
|
|
@ -56,7 +81,7 @@ export const Editor: React.FC<{
|
|||
view.destroy()
|
||||
setView(null)
|
||||
}
|
||||
}, [])
|
||||
}, [onChange, placeholder])
|
||||
|
||||
// Update view state when `value` changed
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Popover } from "@headlessui/react"
|
|||
import { useFetcher, useLoaderData, useParams } from "@remix-run/react"
|
||||
import clsx from "clsx"
|
||||
import dayjs from "dayjs"
|
||||
import { useEffect, useState } from "react"
|
||||
import { useCallback, useEffect, useState } from "react"
|
||||
import { DashboardMain } from "~/components/dashboard/DashboardMain"
|
||||
import { Button } from "~/components/ui/Button"
|
||||
import { getPageVisibility } from "~/lib/page-helpers"
|
||||
|
|
@ -14,7 +14,6 @@ import {
|
|||
type LoaderFunction,
|
||||
redirect,
|
||||
} from "@remix-run/node"
|
||||
import ReactCodeMirror from "@uiw/react-codemirror"
|
||||
import { siteController } from "~/controllers/site.controller"
|
||||
import { getAuthUser } from "~/lib/auth.server"
|
||||
import { getSite } from "~/models/site.model"
|
||||
|
|
@ -22,6 +21,7 @@ import { z } from "zod"
|
|||
import toast from "react-hot-toast"
|
||||
import { Input } from "~/components/ui/Input"
|
||||
import { getSiteLink } from "~/lib/helpers"
|
||||
import { Editor } from "~/components/ui/Editor"
|
||||
|
||||
export const loader: LoaderFunction = async ({ request, params }) => {
|
||||
const user = await getAuthUser(request)
|
||||
|
|
@ -139,6 +139,11 @@ export default function SubdomainEditor() {
|
|||
}
|
||||
}, [fetcher.type])
|
||||
|
||||
const handleEditorContentChange = useCallback(
|
||||
(value) => updateValue("content", value),
|
||||
[]
|
||||
)
|
||||
|
||||
return (
|
||||
<DashboardMain fullWidth>
|
||||
<header className="flex justify-between absolute top-0 left-0 right-0 z-10 px-5 h-14 border-b items-center text-sm">
|
||||
|
|
@ -229,15 +234,16 @@ export default function SubdomainEditor() {
|
|||
name="title"
|
||||
value={values.title}
|
||||
onChange={(e) => updateValue("title", e.target.value)}
|
||||
className="h-12 ml-1 inline-flex items-center border-none text-2xl font-bold w-full focus:outline-none"
|
||||
className="h-12 ml-1 inline-flex items-center border-none text-3xl font-bold w-full focus:outline-none"
|
||||
placeholder="Title goes here.."
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<div className="">
|
||||
<ReactCodeMirror
|
||||
<Editor
|
||||
value={values.content}
|
||||
onChange={(value) => updateValue("content", value)}
|
||||
onChange={handleEditorContentChange}
|
||||
placeholder="Start writing here.."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { DashboardMain } from "~/components/dashboard/DashboardMain"
|
||||
|
||||
export const loader = () => {
|
||||
return { foo: 1 }
|
||||
}
|
||||
|
||||
export default function SubdomainIndex() {
|
||||
return <DashboardMain>hi</DashboardMain>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.81.0",
|
||||
"@codemirror/commands": "^0.20.0",
|
||||
"@codemirror/history": "^0.19.2",
|
||||
"@codemirror/lang-markdown": "^0.20.0",
|
||||
"@codemirror/language": "^0.20.0",
|
||||
"@codemirror/state": "^0.20.0",
|
||||
"@codemirror/view": "^0.20.3",
|
||||
"@headlessui/react": "^1.6.0",
|
||||
|
|
@ -29,7 +29,6 @@
|
|||
"@remix-run/node": "*",
|
||||
"@remix-run/react": "*",
|
||||
"@remix-run/serve": "*",
|
||||
"@uiw/react-codemirror": "^4.7.0",
|
||||
"@vercel/node": "^1.14.0",
|
||||
"clsx": "^1.1.1",
|
||||
"compression": "^1.7.4",
|
||||
|
|
|
|||
583
pnpm-lock.yaml
583
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue