@scottjgilbert/lexical-blog-editor 1.0.0-beta.1 → 1.0.0
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 +1 -1
- package/build/Editor.d.ts +3 -3
- package/build/Editor.d.ts.map +1 -1
- package/build/Editor.js +7 -14
- package/build/plugins/HorizontalRulePlugin/index.d.ts +2 -0
- package/build/plugins/HorizontalRulePlugin/index.d.ts.map +1 -0
- package/build/plugins/HorizontalRulePlugin/index.js +25 -0
- package/build/themes/PlaygroundEditorTheme.css +4 -0
- package/build/themes/ViewerTheme.css +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -193,7 +193,7 @@ import { Viewer } from "@scottjgilbert/lexical-blog-editor/viewer";
|
|
|
193
193
|
- FloatingTextFormatToolbarPlugin
|
|
194
194
|
- HashtagPlugin
|
|
195
195
|
- HistoryPlugin
|
|
196
|
-
-
|
|
196
|
+
- HorizontalRulePlugin
|
|
197
197
|
- ImagesPlugin
|
|
198
198
|
- KeywordsPlugin
|
|
199
199
|
- LayoutPlugin
|
package/build/Editor.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { EditorState } from "lexical";
|
|
1
|
+
import type { EditorState } from "lexical";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import "./index.css";
|
|
4
4
|
export interface EditorProps {
|
|
5
5
|
placeholder?: string;
|
|
6
6
|
initialState?: EditorState;
|
|
7
|
-
onChange: (state: EditorState
|
|
7
|
+
onChange: (state: EditorState) => void;
|
|
8
8
|
}
|
|
9
9
|
export declare const EditorComponent: ({ placeholder, onChange, }: {
|
|
10
10
|
placeholder?: string;
|
|
11
|
-
onChange: (state: EditorState
|
|
11
|
+
onChange: (state: EditorState) => void;
|
|
12
12
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
13
13
|
/**
|
|
14
14
|
* A full Rich Text Editor component.
|
package/build/Editor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"AA+DA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAM3C,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,OAAO,aAAa,CAAC;AAcrB,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,eAAe,GAAI,4BAG7B;IACD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACxC,4CAyIA,CAAC;AAEF;;;;GAIG;AAEH,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA8BxC,CAAC"}
|
package/build/Editor.js
CHANGED
|
@@ -7,7 +7,6 @@ import { CheckListPlugin } from "@lexical/react/LexicalCheckListPlugin";
|
|
|
7
7
|
import { ClearEditorPlugin } from "@lexical/react/LexicalClearEditorPlugin";
|
|
8
8
|
import { ClickableLinkPlugin } from "@lexical/react/LexicalClickableLinkPlugin";
|
|
9
9
|
import { HashtagPlugin } from "@lexical/react/LexicalHashtagPlugin";
|
|
10
|
-
// import { HorizontalRulePlugin } from "@lexical/react/LexicalHorizontalRulePlugin";
|
|
11
10
|
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
|
|
12
11
|
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
|
13
12
|
import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin";
|
|
@@ -33,6 +32,7 @@ import EquationsPlugin from "./plugins/EquationsPlugin";
|
|
|
33
32
|
import FigmaPlugin from "./plugins/FigmaPlugin";
|
|
34
33
|
import FloatingLinkEditorPlugin from "./plugins/FloatingLinkEditorPlugin";
|
|
35
34
|
import FloatingTextFormatToolbarPlugin from "./plugins/FloatingTextFormatToolbarPlugin";
|
|
35
|
+
import HorizontalRulePlugin from "./plugins/HorizontalRulePlugin";
|
|
36
36
|
import ImagesPlugin from "./plugins/ImagesPlugin";
|
|
37
37
|
import KeywordsPlugin from "./plugins/KeywordsPlugin";
|
|
38
38
|
import { LayoutPlugin } from "./plugins/LayoutPlugin/LayoutPlugin";
|
|
@@ -51,7 +51,6 @@ import YouTubePlugin from "./plugins/YouTubePlugin";
|
|
|
51
51
|
import ContentEditable from "./ui/ContentEditable";
|
|
52
52
|
import { $createHeadingNode } from "@lexical/rich-text";
|
|
53
53
|
import { $getRoot, $createParagraphNode, defineExtension, $createTextNode, } from "lexical";
|
|
54
|
-
import { $generateHtmlFromNodes } from "@lexical/html";
|
|
55
54
|
import { LexicalExtensionComposer } from "@lexical/react/LexicalExtensionComposer";
|
|
56
55
|
import { TableContext } from "./plugins/TablePlugin";
|
|
57
56
|
import { ToolbarContext } from "./context/ToolbarContext";
|
|
@@ -61,14 +60,14 @@ import PlaygroundNodes from "./nodes/PlaygroundNodes/PlaygroundNodes";
|
|
|
61
60
|
import { buildHTMLConfig } from "./buildHTMLConfig";
|
|
62
61
|
import "./index.css";
|
|
63
62
|
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
|
|
64
|
-
import { HorizontalRuleExtension } from "@lexical/extension";
|
|
63
|
+
// import { HorizontalRuleExtension } from "@lexical/extension";
|
|
65
64
|
function $prepopulatedRichText() {
|
|
66
65
|
const root = $getRoot();
|
|
67
66
|
const heading = $createHeadingNode("h1");
|
|
68
|
-
heading.append($createTextNode("
|
|
67
|
+
heading.append($createTextNode("Rich Blog Editor"));
|
|
69
68
|
root.append(heading);
|
|
70
69
|
const paragraph = $createParagraphNode();
|
|
71
|
-
paragraph.append($createTextNode("Welcome to the rich
|
|
70
|
+
paragraph.append($createTextNode("Welcome to the rich blog editor!"));
|
|
72
71
|
root.append(paragraph);
|
|
73
72
|
}
|
|
74
73
|
export const EditorComponent = ({ placeholder = "Enter some text...", onChange, }) => {
|
|
@@ -89,13 +88,7 @@ export const EditorComponent = ({ placeholder = "Enter some text...", onChange,
|
|
|
89
88
|
useEffect(() => {
|
|
90
89
|
// most listeners return a teardown function that can be called to clean them up.
|
|
91
90
|
return editor.registerUpdateListener(({ editorState }) => {
|
|
92
|
-
|
|
93
|
-
onChange(editorState,
|
|
94
|
-
//Need to modify generateHtml to auto-inject classes for styling
|
|
95
|
-
'<div class="lexical-blog-output">' +
|
|
96
|
-
$generateHtmlFromNodes(editor) +
|
|
97
|
-
"</div>");
|
|
98
|
-
});
|
|
91
|
+
onChange(editorState);
|
|
99
92
|
});
|
|
100
93
|
}, [editor, onChange]);
|
|
101
94
|
return null;
|
|
@@ -113,7 +106,7 @@ export const EditorComponent = ({ placeholder = "Enter some text...", onChange,
|
|
|
113
106
|
window.removeEventListener("resize", updateViewPortWidth);
|
|
114
107
|
};
|
|
115
108
|
}, [isSmallWidthViewport]);
|
|
116
|
-
return (_jsxs(_Fragment, { children: [_jsx(ToolbarPlugin, { editor: editor, activeEditor: activeEditor, setActiveEditor: setActiveEditor, setIsLinkEditMode: setIsLinkEditMode }), _jsx(ShortcutsPlugin, { editor: activeEditor, setIsLinkEditMode: setIsLinkEditMode }), _jsxs("div", { className: `editor-container`, children: [_jsx(DragDropPaste, {}), _jsx(AutoFocusPlugin, {}), _jsx(ClearEditorPlugin, {}), _jsx(ComponentPickerPlugin, {}), _jsx(EmojiPickerPlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(EmojisPlugin, {}), _jsx(HashtagPlugin, {}), _jsx(KeywordsPlugin, {}), _jsx(SpeechToTextPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(DateTimePlugin, {}), _jsx(HistoryPlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx("div", { className: "editor-scroller", children: _jsx("div", { className: "editor", ref: onRef, children: _jsx(ContentEditable, { placeholder: placeholder }) }) }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: onChange }), _jsx(MarkdownShortcutPlugin, {}), _jsx(CodeHighlightShikiPlugin, {}), _jsx(ListPlugin, { hasStrictIndent: true }), _jsx(CheckListPlugin, {}), _jsx(TablePlugin, {}), _jsx(TableCellResizer, {}), _jsx(TableScrollShadowPlugin, {}), _jsx(ImagesPlugin, {}), _jsx(LinkPlugin, { hasLinkAttributes: true }), _jsx(TwitterPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(FigmaPlugin, {}), _jsx(ClickableLinkPlugin, { disabled: isEditable }), _jsx(EquationsPlugin, {}), _jsx(TabFocusPlugin, {}), _jsx(TabIndentationPlugin, { maxIndent: 7 }), _jsx(CollapsiblePlugin, {}), _jsx(LayoutPlugin, {}), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem, isLinkEditMode: isLinkEditMode, setIsLinkEditMode: setIsLinkEditMode }), _jsx(TableCellActionMenuPlugin, { anchorElem: floatingAnchorElem, cellMerge: true })] })), floatingAnchorElem && !isSmallWidthViewport && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), _jsx(TableHoverActionsV2Plugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode })] })), _jsx(ActionsPlugin, { shouldPreserveNewLinesInMarkdown: true, useCollabV2: false })] }), " "] }));
|
|
109
|
+
return (_jsxs(_Fragment, { children: [_jsx(ToolbarPlugin, { editor: editor, activeEditor: activeEditor, setActiveEditor: setActiveEditor, setIsLinkEditMode: setIsLinkEditMode }), _jsx(ShortcutsPlugin, { editor: activeEditor, setIsLinkEditMode: setIsLinkEditMode }), _jsxs("div", { className: `editor-container`, children: [_jsx(DragDropPaste, {}), _jsx(AutoFocusPlugin, {}), _jsx(ClearEditorPlugin, {}), _jsx(ComponentPickerPlugin, {}), _jsx(EmojiPickerPlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(EmojisPlugin, {}), _jsx(HashtagPlugin, {}), _jsx(HorizontalRulePlugin, {}), _jsx(KeywordsPlugin, {}), _jsx(SpeechToTextPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(DateTimePlugin, {}), _jsx(HistoryPlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx("div", { className: "editor-scroller", children: _jsx("div", { className: "editor", ref: onRef, children: _jsx(ContentEditable, { placeholder: placeholder }) }) }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: onChange }), _jsx(MarkdownShortcutPlugin, {}), _jsx(CodeHighlightShikiPlugin, {}), _jsx(ListPlugin, { hasStrictIndent: true }), _jsx(CheckListPlugin, {}), _jsx(TablePlugin, {}), _jsx(TableCellResizer, {}), _jsx(TableScrollShadowPlugin, {}), _jsx(ImagesPlugin, {}), _jsx(LinkPlugin, { hasLinkAttributes: true }), _jsx(TwitterPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(FigmaPlugin, {}), _jsx(ClickableLinkPlugin, { disabled: isEditable }), _jsx(EquationsPlugin, {}), _jsx(TabFocusPlugin, {}), _jsx(TabIndentationPlugin, { maxIndent: 7 }), _jsx(CollapsiblePlugin, {}), _jsx(LayoutPlugin, {}), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem, isLinkEditMode: isLinkEditMode, setIsLinkEditMode: setIsLinkEditMode }), _jsx(TableCellActionMenuPlugin, { anchorElem: floatingAnchorElem, cellMerge: true })] })), floatingAnchorElem && !isSmallWidthViewport && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), _jsx(TableHoverActionsV2Plugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode })] })), _jsx(ActionsPlugin, { shouldPreserveNewLinesInMarkdown: true, useCollabV2: false })] }), " "] }));
|
|
117
110
|
};
|
|
118
111
|
/**
|
|
119
112
|
* A full Rich Text Editor component.
|
|
@@ -128,7 +121,7 @@ export const Editor = ({ placeholder = "Enter some text...", initialState, onCha
|
|
|
128
121
|
namespace: "BlogEditor",
|
|
129
122
|
nodes: PlaygroundNodes,
|
|
130
123
|
theme: PlaygroundEditorTheme,
|
|
131
|
-
dependencies: [HorizontalRuleExtension],
|
|
124
|
+
// dependencies: [HorizontalRuleExtension],
|
|
132
125
|
}), [initialState]);
|
|
133
126
|
return (_jsx("div", { className: "editor-shell", children: _jsx(LexicalExtensionComposer, { extension: app, contentEditable: null, children: _jsx(TableContext, { children: _jsx(ToolbarContext, { children: _jsx(EditorComponent, { placeholder: placeholder, onChange: onChange }) }) }) }) }));
|
|
134
127
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/HorizontalRulePlugin/index.tsx"],"names":[],"mappings":"AAgBA,MAAM,CAAC,OAAO,UAAU,oBAAoB,IAAI,IAAI,CA4BnD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
3
|
+
import { $createHorizontalRuleNode, INSERT_HORIZONTAL_RULE_COMMAND, } from "@lexical/extension";
|
|
4
|
+
import { $createParagraphNode, $getSelection, $isRangeSelection, $isRootOrShadowRoot, COMMAND_PRIORITY_EDITOR, } from "lexical";
|
|
5
|
+
import { useEffect } from "react";
|
|
6
|
+
export default function HorizontalRulePlugin() {
|
|
7
|
+
const [editor] = useLexicalComposerContext();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
return editor.registerCommand(INSERT_HORIZONTAL_RULE_COMMAND, () => {
|
|
10
|
+
const selection = $getSelection();
|
|
11
|
+
if (!$isRangeSelection(selection)) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const horizontalRuleNode = $createHorizontalRuleNode();
|
|
15
|
+
selection.insertNodes([horizontalRuleNode]);
|
|
16
|
+
if ($isRootOrShadowRoot(horizontalRuleNode.getParent())) {
|
|
17
|
+
const paragraphNode = $createParagraphNode();
|
|
18
|
+
horizontalRuleNode.insertAfter(paragraphNode);
|
|
19
|
+
paragraphNode.select();
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
}, COMMAND_PRIORITY_EDITOR);
|
|
23
|
+
}, [editor]);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
@@ -167,6 +167,7 @@
|
|
|
167
167
|
overflow-x: auto;
|
|
168
168
|
position: relative;
|
|
169
169
|
tab-size: 2;
|
|
170
|
+
white-space: pre;
|
|
170
171
|
}
|
|
171
172
|
.PlaygroundEditorTheme__code:before {
|
|
172
173
|
content: attr(data-gutter);
|
|
@@ -181,6 +182,9 @@
|
|
|
181
182
|
text-align: right;
|
|
182
183
|
min-width: 25px;
|
|
183
184
|
}
|
|
185
|
+
.PlaygroundEditorTheme__code span {
|
|
186
|
+
white-space: pre;
|
|
187
|
+
}
|
|
184
188
|
.PlaygroundEditorTheme__tableScrollableWrapper {
|
|
185
189
|
overflow-x: auto;
|
|
186
190
|
margin: 0px 25px 30px 0px;
|
|
@@ -167,6 +167,10 @@
|
|
|
167
167
|
overflow-x: auto;
|
|
168
168
|
position: relative;
|
|
169
169
|
tab-size: 2;
|
|
170
|
+
white-space: pre;
|
|
171
|
+
}
|
|
172
|
+
.ViewerTheme__code span {
|
|
173
|
+
white-space: pre;
|
|
170
174
|
}
|
|
171
175
|
/* Apply padding if the pre is empty OR if the last child isn't a span */
|
|
172
176
|
.ViewerTheme__code:empty::after,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scottjgilbert/lexical-blog-editor",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
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",
|