@scottjgilbert/lexical-blog-editor 0.1.4-beta.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -55
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,108 +1,263 @@
|
|
|
1
|
-
# lexical-blog-editor
|
|
1
|
+
# @scottjgilbert/lexical-blog-editor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img alt="NPM version" src="https://img.shields.io/npm/v/@scottjgilbert/lexical-blog-editor.svg?style=for-the-badge&labelColor=000000">
|
|
4
|
+
<img alt="License" src="https://img.shields.io/npm/l/@scottjgilbert/lexical-blog-editor.svg?style=for-the-badge&labelColor=000000">
|
|
5
|
+
|
|
6
|
+
A feature-rich, production-ready rich text editor for blog content, built on Meta's [Lexical](https://lexical.dev/) framework. This package provides a comprehensive editing experience with extensive plugin support, custom nodes, and a full-featured toolbar.
|
|
7
|
+
|
|
8
|
+
> ⚠️ **Note**: This package is currently in beta. A rendering component for displaying saved content as DOM is under active development.
|
|
4
9
|
|
|
5
10
|
## Installation
|
|
6
11
|
|
|
7
12
|
```bash
|
|
8
|
-
npm install lexical-blog-editor
|
|
13
|
+
npm install @scottjgilbert/lexical-blog-editor
|
|
14
|
+
# or
|
|
15
|
+
pnpm add @scottjgilbert/lexical-blog-editor
|
|
16
|
+
# or
|
|
17
|
+
yarn add @scottjgilbert/lexical-blog-editor
|
|
9
18
|
```
|
|
10
19
|
|
|
11
|
-
##
|
|
20
|
+
## Requirements
|
|
12
21
|
|
|
13
22
|
This package requires the following peer dependencies:
|
|
14
23
|
|
|
15
|
-
-
|
|
16
|
-
-
|
|
24
|
+
- React 18.0.0 or higher
|
|
25
|
+
- React DOM 18.0.0 or higher
|
|
26
|
+
- Lexical 0.39.0 or higher
|
|
17
27
|
|
|
18
28
|
## Usage
|
|
19
29
|
|
|
20
|
-
###
|
|
21
|
-
|
|
22
|
-
The Editor component provides a rich text editor powered by Lexical.
|
|
30
|
+
### Basic Implementation
|
|
23
31
|
|
|
24
32
|
```tsx
|
|
25
|
-
import { Editor } from
|
|
26
|
-
import { EditorState } from
|
|
33
|
+
import { Editor } from "@scottjgilbert/lexical-blog-editor";
|
|
34
|
+
import type { EditorState } from "lexical";
|
|
27
35
|
|
|
28
|
-
function
|
|
36
|
+
function MyBlogEditor() {
|
|
29
37
|
const handleChange = (editorState: EditorState) => {
|
|
30
|
-
//
|
|
38
|
+
// Access and serialize the editor state
|
|
31
39
|
editorState.read(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
const json = JSON.stringify(editorState.toJSON());
|
|
41
|
+
console.log("Editor content:", json);
|
|
42
|
+
// Save to your database, state management, etc.
|
|
35
43
|
});
|
|
36
44
|
};
|
|
37
45
|
|
|
38
46
|
return (
|
|
39
47
|
<Editor
|
|
40
48
|
onChange={handleChange}
|
|
41
|
-
placeholder="Start writing..."
|
|
49
|
+
placeholder="Start writing your blog post..."
|
|
42
50
|
/>
|
|
43
51
|
);
|
|
44
52
|
}
|
|
45
53
|
```
|
|
46
54
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- `onChange?: (editorState: EditorState) => void` - Callback fired when editor content changes
|
|
50
|
-
- `initialContent?: string` - Initial editor content as a serialized EditorState
|
|
51
|
-
- `placeholder?: string` - Placeholder text when editor is empty (default: "Enter some text...")
|
|
52
|
-
- `editorState?: string` - Controlled editor state as a serialized EditorState
|
|
53
|
-
|
|
54
|
-
### Viewer Component
|
|
55
|
-
|
|
56
|
-
The Viewer component renders read-only rich text content.
|
|
55
|
+
### With Initial Content
|
|
57
56
|
|
|
58
57
|
```tsx
|
|
59
|
-
import {
|
|
58
|
+
import { Editor } from "@scottjgilbert/lexical-blog-editor";
|
|
59
|
+
import type { EditorState } from "lexical";
|
|
60
|
+
|
|
61
|
+
function MyBlogEditor({ savedContent }: { savedContent?: EditorState }) {
|
|
62
|
+
const handleChange = (editorState: EditorState) => {
|
|
63
|
+
// Handle changes
|
|
64
|
+
};
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
return (
|
|
67
|
+
<Editor
|
|
68
|
+
initialState={savedContent}
|
|
69
|
+
onChange={handleChange}
|
|
70
|
+
placeholder="Continue writing..."
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
63
73
|
}
|
|
64
74
|
```
|
|
65
75
|
|
|
66
|
-
|
|
76
|
+
## API Reference
|
|
77
|
+
|
|
78
|
+
### Editor Component
|
|
79
|
+
|
|
80
|
+
#### Props
|
|
67
81
|
|
|
68
|
-
|
|
82
|
+
| Prop | Type | Default | Description |
|
|
83
|
+
| -------------- | ------------------------------------ | ---------------------- | --------------------------------------------------------------------------------- |
|
|
84
|
+
| `onChange` | `(editorState: EditorState) => void` | **Required** | Callback fired whenever the editor content changes |
|
|
85
|
+
| `placeholder` | `string` | `"Enter some text..."` | Placeholder text displayed when the editor is empty |
|
|
86
|
+
| `initialState` | `EditorState` | `undefined` | Initial editor content state. If not provided, displays a default welcome message |
|
|
69
87
|
|
|
70
88
|
## Features
|
|
71
89
|
|
|
72
|
-
|
|
90
|
+
### Rich Text Editing
|
|
91
|
+
|
|
92
|
+
- **Text Formatting**: Bold, italic, underline, strikethrough, subscript, superscript, code
|
|
93
|
+
- **Headings**: H1 through H6
|
|
94
|
+
- **Text Alignment**: Left, center, right, justify
|
|
95
|
+
- **Font Sizes**: Adjustable text size
|
|
96
|
+
- **Text Color & Background**: Custom text and highlight colors
|
|
97
|
+
- **Lists**: Ordered lists, unordered lists, and checklist support
|
|
98
|
+
- **Quotes & Code Blocks**: Block quotes and syntax-highlighted code blocks
|
|
99
|
+
- **Indentation**: Tab indentation with nesting support (up to 7 levels)
|
|
100
|
+
|
|
101
|
+
### Content Blocks
|
|
102
|
+
|
|
103
|
+
- **Tables**: Fully-featured tables with cell merging, resizing, and hover actions
|
|
104
|
+
- **Images**: Upload and embed images with captions and resizing
|
|
105
|
+
- **Embeds**: YouTube videos, Twitter/X posts, Figma designs
|
|
106
|
+
- **Equations**: LaTeX/KaTeX mathematical equation support
|
|
107
|
+
- **Horizontal Rules**: Visual section dividers
|
|
108
|
+
- **Page Breaks**: Print-friendly page break markers
|
|
109
|
+
- **Layouts**: Multi-column layouts with customizable containers
|
|
110
|
+
- **Collapsible Sections**: Expandable/collapsible content blocks
|
|
111
|
+
- **Date/Time**: Insert formatted date and time stamps
|
|
112
|
+
|
|
113
|
+
### Interactive Elements
|
|
114
|
+
|
|
115
|
+
- **Links**: Auto-detection, manual insertion, and inline editing
|
|
116
|
+
- **Mentions**: @mention support with autocomplete
|
|
117
|
+
- **Hashtags**: Automatic #hashtag detection
|
|
118
|
+
- **Keywords**: Special keyword highlighting
|
|
119
|
+
- **Emojis**: Emoji picker with search and categories
|
|
120
|
+
- **Polls**: Interactive poll creation (visual component)
|
|
121
|
+
|
|
122
|
+
### Advanced Features
|
|
123
|
+
|
|
124
|
+
- **Markdown Shortcuts**: Type Markdown syntax for quick formatting
|
|
125
|
+
- **Drag & Drop**: Drag and drop images, reorder blocks
|
|
126
|
+
- **Speech to Text**: Voice input support (browser-dependent)
|
|
127
|
+
- **Component Picker**: Slash commands (`/`) to quickly insert components
|
|
128
|
+
- **Floating Toolbars**: Context-aware formatting toolbars
|
|
129
|
+
- **Auto-linking**: Automatically converts URLs to clickable links
|
|
130
|
+
- **Syntax Highlighting**: Code blocks with Shiki-powered syntax highlighting
|
|
131
|
+
- **Undo/Redo**: Full history support with keyboard shortcuts
|
|
132
|
+
- **Keyboard Shortcuts**: Comprehensive keyboard shortcut system
|
|
133
|
+
- **Copy/Paste**: Smart paste handling with format preservation
|
|
134
|
+
|
|
135
|
+
### Included Plugins
|
|
136
|
+
|
|
137
|
+
<details>
|
|
138
|
+
<summary>View all plugins (40+)</summary>
|
|
139
|
+
|
|
140
|
+
- ActionsPlugin
|
|
141
|
+
- AutoEmbedPlugin
|
|
142
|
+
- AutoFocusPlugin
|
|
143
|
+
- AutoLinkPlugin
|
|
144
|
+
- CheckListPlugin
|
|
145
|
+
- ClearEditorPlugin
|
|
146
|
+
- ClickableLinkPlugin
|
|
147
|
+
- CodeActionMenuPlugin
|
|
148
|
+
- CodeHighlightShikiPlugin
|
|
149
|
+
- CollapsiblePlugin
|
|
150
|
+
- ComponentPickerPlugin
|
|
151
|
+
- DateTimePlugin
|
|
152
|
+
- DragDropPastePlugin
|
|
153
|
+
- DraggableBlockPlugin
|
|
154
|
+
- EmojiPickerPlugin
|
|
155
|
+
- EmojisPlugin
|
|
156
|
+
- EquationsPlugin
|
|
157
|
+
- FigmaPlugin
|
|
158
|
+
- FloatingLinkEditorPlugin
|
|
159
|
+
- FloatingTextFormatToolbarPlugin
|
|
160
|
+
- HashtagPlugin
|
|
161
|
+
- HistoryPlugin
|
|
162
|
+
- HorizontalRulePlugin
|
|
163
|
+
- ImagesPlugin
|
|
164
|
+
- KeywordsPlugin
|
|
165
|
+
- LayoutPlugin
|
|
166
|
+
- LinkPlugin
|
|
167
|
+
- ListPlugin
|
|
168
|
+
- MarkdownShortcutPlugin
|
|
169
|
+
- MentionsPlugin
|
|
170
|
+
- PageBreakPlugin
|
|
171
|
+
- RichTextPlugin
|
|
172
|
+
- ShortcutsPlugin
|
|
173
|
+
- SpeechToTextPlugin
|
|
174
|
+
- TabFocusPlugin
|
|
175
|
+
- TabIndentationPlugin
|
|
176
|
+
- TablePlugin (with cell resizing, merging, and hover actions)
|
|
177
|
+
- ToolbarPlugin
|
|
178
|
+
- TwitterPlugin
|
|
179
|
+
- YouTubePlugin
|
|
180
|
+
|
|
181
|
+
</details>
|
|
182
|
+
|
|
183
|
+
### Custom Nodes
|
|
184
|
+
|
|
185
|
+
The editor includes over 25 custom node types:
|
|
186
|
+
|
|
187
|
+
- AutoLinkNode, LinkNode
|
|
188
|
+
- CodeNode, CodeHighlightNode
|
|
189
|
+
- CollapsibleContainerNode, CollapsibleContentNode, CollapsibleTitleNode
|
|
190
|
+
- DateTimeNode
|
|
191
|
+
- EmojiNode
|
|
192
|
+
- EquationNode
|
|
193
|
+
- FigmaNode
|
|
194
|
+
- HashtagNode
|
|
195
|
+
- HeadingNode, QuoteNode
|
|
196
|
+
- HorizontalRuleNode
|
|
197
|
+
- ImageNode
|
|
198
|
+
- KeywordNode
|
|
199
|
+
- LayoutContainerNode, LayoutItemNode
|
|
200
|
+
- ListNode, ListItemNode
|
|
201
|
+
- MarkNode
|
|
202
|
+
- MentionNode
|
|
203
|
+
- OverflowNode
|
|
204
|
+
- PageBreakNode
|
|
205
|
+
- PollNode
|
|
206
|
+
- SpecialTextNode
|
|
207
|
+
- TableNode, TableCellNode, TableRowNode
|
|
208
|
+
- TweetNode
|
|
209
|
+
- YouTubeNode
|
|
73
210
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
211
|
+
## Styling
|
|
212
|
+
|
|
213
|
+
The package includes built-in CSS that will be automatically imported. The editor uses CSS classes that can be customized:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
// The editor includes its own styles
|
|
217
|
+
import { Editor } from "@scottjgilbert/lexical-blog-editor";
|
|
218
|
+
// Styles are automatically applied
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Key CSS Classes
|
|
222
|
+
|
|
223
|
+
- `.full-blog-editor-wrapper` - Outermost wrapper
|
|
224
|
+
- `.editor-container` - Main editor container
|
|
225
|
+
- `.editor-scroller` - Scrollable editor area
|
|
226
|
+
- `.editor` - ContentEditable wrapper
|
|
227
|
+
- Various node-specific classes for custom styling
|
|
228
|
+
|
|
229
|
+
You can override these classes in your own CSS to customize the appearance.
|
|
80
230
|
|
|
81
231
|
## TypeScript Support
|
|
82
232
|
|
|
83
|
-
This package
|
|
233
|
+
This package is written in TypeScript and includes full type definitions. All exports are typed:
|
|
84
234
|
|
|
85
235
|
```tsx
|
|
86
|
-
import type { EditorProps } from
|
|
87
|
-
import type {
|
|
236
|
+
import type { EditorProps } from "@scottjgilbert/lexical-blog-editor";
|
|
237
|
+
import type { EditorState } from "@scottjgilbert/lexical-blog-editor";
|
|
88
238
|
```
|
|
89
239
|
|
|
90
|
-
##
|
|
240
|
+
## Roadmap
|
|
91
241
|
|
|
92
|
-
|
|
242
|
+
- [ ] **Viewer Component**: Dedicated component for rendering saved EditorState as read-only DOM content
|
|
243
|
+
- [ ] **Server-Side Rendering**: Enhanced SSR support
|
|
93
244
|
|
|
94
|
-
|
|
95
|
-
- `.editor-container` - Main editor container
|
|
96
|
-
- `.editor-input` - ContentEditable element
|
|
97
|
-
- `.editor-placeholder` - Placeholder text
|
|
98
|
-
- `.editor-paragraph`, `.editor-heading-h1`, etc. - Text styling classes
|
|
245
|
+
## Browser Support
|
|
99
246
|
|
|
100
|
-
|
|
101
|
-
- `.viewer-container` - Main viewer container
|
|
102
|
-
- `.viewer-content` - Content display element
|
|
103
|
-
- `.viewer-paragraph`, `.viewer-heading-h1`, etc. - Text styling classes
|
|
247
|
+
The editor supports all modern browsers:
|
|
104
248
|
|
|
105
|
-
|
|
249
|
+
- Chrome/Edge (latest)
|
|
250
|
+
- Firefox (latest)
|
|
251
|
+
- Safari (latest)
|
|
252
|
+
|
|
253
|
+
## Contributing
|
|
106
254
|
|
|
107
|
-
|
|
255
|
+
This is an open-source project. Contributions, issues, and feature requests are welcome!
|
|
256
|
+
|
|
257
|
+
## Acknowledgments
|
|
258
|
+
|
|
259
|
+
Built on top of Meta's [Lexical](https://lexical.dev/) framework. This package is a wrapper of a modified version of the Lexical Playground editor, tailored specifically for blog content creation.
|
|
260
|
+
|
|
261
|
+
## License
|
|
108
262
|
|
|
263
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scottjgilbert/lexical-blog-editor",
|
|
3
|
-
"version": "0.1.4
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Prebuilt components for editing and rendering rich blog content with Lexical. Modified wrapper of the Lexical Playground editor.",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|