Editor
A feature-rich WYSIWYG text editor component with formatting tools, undo/redo support, font selection, and live preview mode.
Last updated on
A professional, fully-featured rich text editor built with React. Includes comprehensive formatting capabilities, keyboard shortcuts, font selection, real-time preview mode, and intuitive toolbar controls.
Installation
npx shadcn@latest add @grenish/editorThis requires the @grenish registry in your components.json. See the installation guide for setup.
Manual Dependencies
If you prefer manual installation, add the base components:
npx shadcn@latest add card button select toggle-group tooltip input-group dialogUsage
import MainEditor from "@/components/tools/editor"
export default function EditorDemo() {
return <MainEditor />
}"use client";
import { Card, CardFooter } from "@/components/ui/card";
import EditorToolbar from "./toolbar";
import EditorBody from "./editor-body";
import { Button } from "@/components/ui/button";
import { useEditorState } from "./hooks/useEditorState";
import { useTextFormatting } from "./hooks/useTextFormatting";
import { useState } from "react";
import DeleteButton from "../delete-button";
export default function MainEditor() {
const editor = useEditorState();
const formatting = useTextFormatting(editor.editorRef);
const [isPreviewMode, setIsPreviewMode] = useState(false);
const togglePreviewMode = () => {
setIsPreviewMode(!isPreviewMode);
};
return (
<Card className="w-full">
<EditorToolbar
editorRef={editor.editorRef}
fontFamily={editor.fontFamily}
setFont={editor.setFont}
canUndo={editor.canUndo}
canRedo={editor.canRedo}
onUndo={editor.undo}
onRedo={editor.redo}
onBold={() => {
if (editor.editorRef.current) {
editor.editorRef.current.focus();
}
editor.toggleFormat("bold");
}}
onItalic={() => {
if (editor.editorRef.current) {
editor.editorRef.current.focus();
}
editor.toggleFormat("italic");
}}
onUnderline={() => {
if (editor.editorRef.current) {
editor.editorRef.current.focus();
}
editor.toggleFormat("underline");
}}
onHeading={(heading: "h1" | "h2") => {
if (editor.editorRef.current) {
editor.editorRef.current.focus();
}
editor.applyFormat(heading);
}}
onBulletList={() => {
if (editor.editorRef.current) {
editor.editorRef.current.focus();
document.execCommand("insertUnorderedList");
editor.updateContent(editor.editorRef.current.innerHTML);
}
}}
onNumberList={() => {
if (editor.editorRef.current) {
editor.editorRef.current.focus();
document.execCommand("insertOrderedList");
editor.updateContent(editor.editorRef.current.innerHTML);
}
}}
onInsertLink={() => {
// LinkPrompt handles the link insertion, we just need to update content
if (editor.editorRef.current) {
editor.editorRef.current.focus();
editor.updateContent(editor.editorRef.current.innerHTML);
}
}}
onInsertImage={() => {
const url = prompt("Enter the image URL:");
if (url && editor.editorRef.current) {
editor.editorRef.current.focus();
document.execCommand("insertImage", false, url);
editor.updateContent(editor.editorRef.current.innerHTML);
}
}}
activeFormats={formatting.activeFormats}
isPreviewMode={isPreviewMode}
onTogglePreview={togglePreviewMode}
/>
<EditorBody
editorRef={editor.editorRef}
fontFamily={editor.fontFamily}
onInput={editor.handleInput}
onKeyDown={editor.handleKeyDown}
onUpdateFormats={formatting.updateActiveFormats}
isPreviewMode={isPreviewMode}
/>
<CardFooter className="gap-1">
<Button size={"sm"}>Save</Button>
<DeleteButton size={"sm"} />
</CardFooter>
</Card>
);
}File Structure
Source Code
Features
- Rich Text Editing: Support for bold, italic, underline, headings, and list formatting
- Multiple Font Selection: Choose from 10 different font families including Roboto, Montserrat, Lato, and more
- Undo/Redo Support: Full history support with customizable history size (up to 50 actions)
- Live Preview Mode: Toggle between editing and preview modes to see your content as it will appear
- Keyboard Shortcuts:
- Ctrl+B / Cmd+B: Bold
- Ctrl+I / Cmd+I: Italic
- Ctrl+U / Cmd+U: Underline
- Ctrl+Z / Cmd+Z: Undo
- Ctrl+Y / Cmd+Y or Ctrl+Shift+Z: Redo
- Link & Image Insertion: Easy-to-use dialogs for adding links and images
- Text Formatting Toolbar: Intuitive toolbar with grouped controls for quick access to formatting options
- Empty State Handling: Placeholder text and empty state detection
- Responsive Design: Works seamlessly on different screen sizes
Delete Button
A confirmation-enabled delete button component with customizable dialog content. Safely handles destructive actions with user confirmation.
Google Button
A styled authentication button for Google sign-in with icon and full variants, customizable tooltip, and seamless integration with shadcn Button.