Markdown Editor
sidcn/markdown-editorFreeBlock
A beautiful markdown editor component
Live preview
live · rendered by the registry
Rendered by sidcn on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.siddhesh.cc/r/markdown-editor.jsonSource
1"use client";23import { Bold, Italic, Link, List, ListOrdered } from "lucide-react";4import { marked } from "marked";5import React from "react";6import { Separator } from "@/components/ui/separator";7import { Textarea } from "@/components/ui/textarea";8import { Button } from "@/registry/new-york/components/button";9import { isMac } from "@/registry/new-york/lib/utils";1011export interface MarkdownEditorProps {12 initialValue?: string;13 onChange?: (value: string) => void;14}1516export function MarkdownEditor({17 initialValue = "",18 onChange,19}: MarkdownEditorProps) {20 const [markdown, setMarkdown] = React.useState(initialValue);21 const [parsedHtml, setParsedHtml] = React.useState<string>("");22 const textareaRef = React.useRef<HTMLTextAreaElement>(null);2324 const handleMarkdownChange = React.useCallback(25 (value: string) => {26 setMarkdown(value);27 onChange?.(value);28 },29 [onChange],30 );3132 const parseMarkdown = React.useCallback(33 async (text: string): Promise<string> => {34 try {35 const result = await marked(text, {36 breaks: true,37 gfm: true,38 });39 return result;40 } catch (error) {41 console.error("Error parsing markdown:", error);42 return text;43 }44 },45 [],46 );4748 const insertMarkdown = React.useCallback(49 (before: string, after = "", placeholder = "") => {50 const textarea = textareaRef.current;51 if (!textarea) return;5253 const start = textarea.selectionStart;54 const end = textarea.selectionEnd;55 const selectedText = textarea.value.substring(start, end);5657 // Check if the selected text is already wrapped with the markdown syntax58 const beforeStart = start - before.length;59 const afterEnd = end + after.length;60 const textBefore = textarea.value.substring(beforeStart, start);61 const textAfter = textarea.value.substring(end, afterEnd);6263 const isAlreadyFormatted = textBefore === before && textAfter === after;6465 if (isAlreadyFormatted && selectedText) {66 // Remove the formatting67 const newText =68 textarea.value.substring(0, beforeStart) +69 selectedText +70 textarea.value.substring(afterEnd);7172 handleMarkdownChange(newText);7374 setTimeout(() => {75 textarea.focus();76 textarea.setSelectionRange(77 beforeStart,78// … truncated
What it pulls in
npm packages
Other registry items
