Package Exports
- platejs-customization
- platejs-customization/styles
- platejs-customization/styles.css
Readme
platejs-customization
A powerful, customizable rich-text editor component built on top of Plate.js for React applications.
Quick Start
import { PlateLiteEditor } from "platejs-customization";
// That's it! No CSS import needed ✨
function App() {
return <PlateLiteEditor value={value} onChange={handleChange} />;
}
Works exactly like shadcn/ui - just import the component and use it!
Features
- ✨ Zero Configuration - Just import and use, no CSS import needed!
- 🎨 Fully Customizable - Extensive props for styling and behavior
- 📝 Rich Text Editing - All Plate.js features including:
- Basic formatting (bold, italic, underline, etc.)
- Lists (ordered and unordered)
- Tables
- Code blocks with syntax highlighting
- Media embeds (images, videos)
- Math equations
- Mentions
- Comments and suggestions
- Slash commands
- AI-powered features
- 🎯 TypeScript Support - Full type definitions included
- 🔒 CSS Isolation - Styles don't conflict with your app
- 📦 Optimized - Small bundle size with automatic CSS injection
- 🚀 Production Ready - Works like shadcn/ui components
Installation
# Using pnpm (recommended)
pnpm add platejs-customization platejs react react-dom
# Using npm
npm install platejs-customization platejs react react-dom
# Using yarn
yarn add platejs-customization platejs react react-dom
Peer Dependencies
This package requires the following peer dependencies:
react
>= 18.0.0react-dom
>= 18.0.0platejs
>= 49.0.0
Usage
Basic Example
import { useState } from "react";
import { PlateLiteEditor } from "platejs-customization";
// ✅ No CSS import needed - styles are automatically loaded!
import type { Value } from "platejs";
function App() {
const [value, setValue] = useState<Value>([{ type: "p", children: [{ text: "Hello, world!" }] }]);
const handleChange = (newValue: Value) => {
setValue(newValue);
console.log("Editor content changed:", newValue);
};
return (
<div className="container mx-auto p-4">
<PlateLiteEditor value={value} onChange={handleChange} placeholder="Start typing..." />
</div>
);
}
export default App;
Note: Styles are automatically injected when you use the component - no manual CSS import required!
With Custom Styling
import { PlateLiteEditor } from "platejs-customization";
function CustomEditor({ value, handleChange }) {
return (
<PlateLiteEditor
value={value}
onChange={handleChange}
placeholder="Enter your content here..."
className="max-w-4xl mx-auto p-4"
editorClassName="min-h-[400px] border rounded-lg p-4"
/>
);
}
Read-Only Mode
import { PlateLiteEditor } from "platejs-customization";
function ReadOnlyEditor() {
return <PlateLiteEditor value={content} readOnly={true} />;
}
API Reference
PlateLiteEditor Props
Prop | Type | Default | Description |
---|---|---|---|
value |
Value |
undefined |
The editor content value |
onChange |
(value: Value) => void |
undefined |
Callback fired when content changes |
placeholder |
string |
"Type your message here." |
Placeholder text |
className |
string |
undefined |
CSS class for the container |
editorClassName |
string |
undefined |
CSS class for the editor |
readOnly |
boolean |
false |
Whether the editor is read-only |
autoFocus |
boolean |
false |
Whether to auto-focus on mount |
disabled |
boolean |
false |
Whether the editor is disabled |
Advanced Usage
Custom Editor Kit
import { EditorKit, useEditor } from "platejs-customization";
import { usePlateEditor } from "platejs/react";
// Use the full editor kit
const editor = usePlateEditor({
plugins: EditorKit,
value: initialValue,
});
Using Individual Hooks
import { useDebounce, useIsTouchDevice, useMounted } from "platejs-customization";
function MyComponent() {
const isTouchDevice = useIsTouchDevice();
const isMounted = useMounted();
const debouncedValue = useDebounce(value, 500);
// Your component logic
}
Styling & CSS
Automatic Style Loading
✨ No CSS import needed! Styles are automatically injected when you use the component.
import { PlateLiteEditor } from "platejs-customization";
// That's it! Styles load automatically 🎉
function MyEditor() {
return <PlateLiteEditor value={value} onChange={handleChange} />;
}
CSS Isolation & Layout Integration
The editor CSS is automatically scoped and will NOT affect your application:
- ✅ Works with any layout (sidebar, navbar, etc.)
- ✅ No conflicts with your existing CSS
- ✅ No global style pollution
- ✅ Works with your Tailwind/design system
The component respects your project's existing styles and theme.
Using in Complex Layouts
The editor works seamlessly with any layout structure:
// ✅ Works perfectly with sidebar layouts
function Dashboard() {
return (
<div className="flex">
{/* Your sidebar - NOT affected by editor styles */}
<aside className="w-64 bg-gray-800">
<nav>...</nav>
</aside>
{/* Main content area */}
<main className="flex-1">
{/* Your navbar - NOT affected */}
<header className="bg-white shadow">...</header>
{/* Editor in content area - fully scoped */}
<div className="p-6">
<PlateLiteEditor
value={value}
onChange={handleChange}
className="max-w-4xl"
editorClassName="min-h-[500px] border rounded-lg p-4"
/>
</div>
</main>
</div>
);
}
Custom Styling
You can customize the editor using the provided props:
<PlateLiteEditor
// Container styling (wrapper around editor)
className="max-w-4xl mx-auto my-8"
// Editor content area styling
editorClassName="min-h-[600px] bg-white border-2 border-gray-300 rounded-xl p-6 shadow-lg"
value={value}
onChange={handleChange}
/>
Tailwind CSS Integration
If your project uses Tailwind CSS, the editor styles work alongside it without conflicts:
<div className="container mx-auto p-4">
<h1 className="text-3xl font-bold mb-6">My Editor</h1>
{/* Editor with Tailwind classes */}
<PlateLiteEditor
className="bg-gray-50 rounded-lg shadow-md"
editorClassName="prose prose-lg max-w-none p-8"
value={value}
onChange={handleChange}
/>
</div>
Dark Mode Support
The editor includes built-in dark mode support. Add the dark
class to any parent element:
<div className="dark">
<PlateLiteEditor value={value} onChange={handleChange} />
</div>
Troubleshooting
Problem: Editor doesn't show properly
Solution: Styles are auto-injected. If you still have issues:
- Make sure you're using the latest version:
pnpm update platejs-customization
- Check browser console for any errors
- Ensure your bundler supports dynamic imports
Problem: CSS conflicts with my design system
Solution: The editor uses CSS variables that can be customized:
/* In your global CSS */
:root {
/* Override editor variables if needed */
--primary: your-color;
--radius: your-border-radius;
}
The editor will respect your existing Tailwind configuration.
Problem: Styles not loading in production
Solution: Ensure your bundler includes CSS files in the build:
- Vite: Works out of the box ✅
- Next.js: Works out of the box ✅
- Webpack: Ensure
css-loader
andstyle-loader
are configured
TypeScript
Full TypeScript support is included:
import type { PlateLiteEditorProps, MyEditor } from "platejs-customization";
import type { Value } from "platejs";
// Use types in your components
const props: PlateLiteEditorProps = {
value: myValue,
onChange: handleChange,
};
Dependencies
This package bundles the following Plate.js plugins:
- AI features
- Autoformat
- Basic blocks and marks
- Code blocks
- Tables
- Comments and suggestions
- Media embeds
- Math equations
- And many more!
See the full list in package.json
.
Development
Local Development
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Build the library
pnpm build:lib
# Lint
pnpm lint
Building
# Build library for production
pnpm build:lib
# Generate type declarations only
pnpm build:types
Publishing
# Build and publish to npm
pnpm publish
Note: The prepublishOnly
script will automatically build the library before publishing.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Author
zonaet
Support
For issues and questions, please open an issue on the GitHub repository.
Changelog
See CHANGELOG.md for version history and changes.