@use-kona/editor 0.1.12 → 0.1.14
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/dist/core/createEditable.d.ts +1 -1
- package/dist/core/createEditor.d.ts +3 -1
- package/dist/core/createEditor.js +20 -33
- package/dist/elements/BaseElement.d.ts +1 -1
- package/dist/plugins/AttachmentsPlugin/types.d.ts +3 -3
- package/dist/plugins/BreaksPlugin/BreaksPlugin.d.ts +3 -1
- package/dist/plugins/CodeBlockPlugin/utils.d.ts +1 -1
- package/dist/plugins/HeadingsPlugin/HeadingsPlugin.d.ts +1 -1
- package/dist/plugins/LinksPlugin/LinksPlugin.d.ts +3 -1
- package/dist/plugins/LinksPlugin/index.d.ts +1 -1
- package/dist/plugins/LinksPlugin/types.d.ts +3 -3
- package/dist/plugins/ListsPlugin/ListsPlugin.d.ts +7 -1
- package/dist/plugins/ListsPlugin/ListsPlugin.js +4 -0
- package/dist/plugins/MenuPlugin/Menu.d.ts +1 -1
- package/dist/plugins/MenuPlugin/MenuPlugin.d.ts +1 -1
- package/dist/plugins/MenuPlugin/types.d.ts +1 -1
- package/dist/plugins/NodeIdPlugin/NodeIdPlugin.d.ts +3 -1
- package/dist/plugins/NodeIdPlugin/NodeIdPlugin.js +4 -1
- package/dist/plugins/ShortcutsPlugin/ShortcutsPlugin.d.ts +3 -1
- package/dist/plugins/TableOfContentsPlugin/TableOfContentsPlugin.d.ts +3 -1
- package/dist/types.d.ts +3 -0
- package/package.json +1 -2
- package/src/core/createEditable.tsx +4 -4
- package/src/core/createEditor.ts +31 -27
- package/src/elements/BaseElement.tsx +1 -1
- package/src/plugins/AttachmentsPlugin/types.ts +3 -3
- package/src/plugins/CodeBlockPlugin/utils.ts +1 -1
- package/src/plugins/HeadingsPlugin/HeadingsPlugin.tsx +1 -1
- package/src/plugins/LinksPlugin/index.ts +1 -1
- package/src/plugins/LinksPlugin/types.ts +3 -3
- package/src/plugins/ListsPlugin/ListsPlugin.spec.tsx +1 -1
- package/src/plugins/ListsPlugin/ListsPlugin.tsx +9 -0
- package/src/plugins/MenuPlugin/Menu.tsx +1 -1
- package/src/plugins/MenuPlugin/types.ts +1 -1
- package/src/plugins/NodeIdPlugin/NodeIdPlugin.ts +7 -1
- package/src/types.ts +11 -1
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import type { IPlugin } from '../types';
|
|
2
|
-
export declare const createEditor: (plugins: IPlugin[]) => () => import("slate").BaseEditor & import("slate-react").ReactEditor
|
|
2
|
+
export declare const createEditor: (plugins: IPlugin[]) => () => import("slate").BaseEditor & import("slate-react").ReactEditor & {
|
|
3
|
+
getCommands: <T extends IPlugin>(plugin: new () => T) => T["commands"];
|
|
4
|
+
};
|
|
@@ -3,33 +3,16 @@ import { withHistory } from "slate-history";
|
|
|
3
3
|
import { withReact } from "slate-react";
|
|
4
4
|
const createEditor_createEditor = (plugins)=>()=>{
|
|
5
5
|
const baseEditor = withHistory(withReact(createEditor()));
|
|
6
|
+
const pluginsMap = new Map();
|
|
6
7
|
const editorWithPlugins = plugins.reduce((editor, plugin)=>{
|
|
7
8
|
if (plugin.init) return plugin.init(editor);
|
|
8
9
|
return editor;
|
|
9
10
|
}, baseEditor);
|
|
10
11
|
const { isInline, isVoid, normalizeNode, deleteFragment, deleteBackward, deleteForward } = editorWithPlugins;
|
|
11
|
-
editorWithPlugins.
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const paragraph = {
|
|
16
|
-
type: 'paragraph',
|
|
17
|
-
children: [
|
|
18
|
-
{
|
|
19
|
-
text: ''
|
|
20
|
-
}
|
|
21
|
-
]
|
|
22
|
-
};
|
|
23
|
-
Transforms.insertNodes(editorWithPlugins, paragraph, {
|
|
24
|
-
at: [
|
|
25
|
-
editorWithPlugins.children.length
|
|
26
|
-
]
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
return normalizeNode([
|
|
30
|
-
node,
|
|
31
|
-
path
|
|
32
|
-
]);
|
|
12
|
+
editorWithPlugins.getCommands = (plugin)=>{
|
|
13
|
+
const pluginInstance = pluginsMap.get(plugin);
|
|
14
|
+
if (!pluginInstance) throw new Error(`Plugin ${plugin.name} not found`);
|
|
15
|
+
return pluginInstance.commands;
|
|
33
16
|
};
|
|
34
17
|
editorWithPlugins.isVoid = (element)=>{
|
|
35
18
|
const result = plugins.reduce((result, plugin)=>{
|
|
@@ -150,17 +133,21 @@ const createEditor_createEditor = (plugins)=>()=>{
|
|
|
150
133
|
const plugin = plugins.find((plugin)=>plugin.blocks?.find((b)=>b.type === node.type));
|
|
151
134
|
if (plugin) {
|
|
152
135
|
const match = plugin.blocks?.find((b)=>b.type === node.type);
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
136
|
+
const hasOnBeforeDelete = match?.onBeforeDelete;
|
|
137
|
+
if (!hasOnBeforeDelete) return void deleteFragment(options);
|
|
138
|
+
{
|
|
139
|
+
const result = await match.onBeforeDelete([
|
|
140
|
+
node
|
|
141
|
+
]);
|
|
142
|
+
if (!result) return;
|
|
143
|
+
Transforms.removeNodes(editorWithPlugins, {
|
|
144
|
+
at: path,
|
|
145
|
+
match: (n)=>n.type === node.type
|
|
146
|
+
});
|
|
147
|
+
match?.onDelete?.([
|
|
148
|
+
node
|
|
149
|
+
]);
|
|
150
|
+
}
|
|
164
151
|
} else Transforms.removeNodes(editorWithPlugins, {
|
|
165
152
|
at: path,
|
|
166
153
|
match: (n)=>n.type === node.type
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RenderElementProps } from 'slate-react';
|
|
1
|
+
import type { RenderElementProps } from 'slate-react';
|
|
2
2
|
export declare const BaseElement: (props: RenderElementProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Editor } from 'slate';
|
|
2
|
-
import { RenderElementProps } from 'slate-react';
|
|
3
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import type { Editor } from 'slate';
|
|
2
|
+
import type { RenderElementProps } from 'slate-react';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
4
|
export type Options = {
|
|
5
5
|
onDragEnter?: () => void;
|
|
6
6
|
onDragLeave?: () => void;
|
|
@@ -7,7 +7,9 @@ type Options = {
|
|
|
7
7
|
export declare class BreaksPlugin implements IPlugin {
|
|
8
8
|
private options;
|
|
9
9
|
constructor(options: Options);
|
|
10
|
-
init(editor: Editor): import("slate").BaseEditor & import("slate-react").ReactEditor
|
|
10
|
+
init(editor: Editor): import("slate").BaseEditor & import("slate-react").ReactEditor & {
|
|
11
|
+
getCommands: <T extends IPlugin>(plugin: new () => T) => T["commands"];
|
|
12
|
+
};
|
|
11
13
|
handlers: {
|
|
12
14
|
onKeyDown: (event: KeyboardEvent, editor: Editor) => void;
|
|
13
15
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copied from prism-react-renderer repo
|
|
3
3
|
* https://github.com/FormidableLabs/prism-react-renderer/blob/master/src/utils/normalizeTokens.js
|
|
4
4
|
* */
|
|
5
|
-
import Prism from 'prismjs';
|
|
5
|
+
import type Prism from 'prismjs';
|
|
6
6
|
type PrismToken = Prism.Token;
|
|
7
7
|
type Token = {
|
|
8
8
|
types: string[];
|
|
@@ -6,7 +6,9 @@ export declare class LinksPlugin implements IPlugin {
|
|
|
6
6
|
private options;
|
|
7
7
|
static LINK_TYPE: string;
|
|
8
8
|
constructor(options: Options);
|
|
9
|
-
init(editor: Editor): import("slate").BaseEditor & import("slate-react").ReactEditor
|
|
9
|
+
init(editor: Editor): import("slate").BaseEditor & import("slate-react").ReactEditor & {
|
|
10
|
+
getCommands: <T extends IPlugin>(plugin: new () => T) => T["commands"];
|
|
11
|
+
};
|
|
10
12
|
blocks: {
|
|
11
13
|
isInline: boolean;
|
|
12
14
|
type: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { LinksPlugin } from './LinksPlugin';
|
|
2
|
-
export {
|
|
2
|
+
export type { OptionsMethods } from './types';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { LINK_ELEMENT } from './constants';
|
|
2
|
-
import { Editor } from 'slate';
|
|
3
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import type { LINK_ELEMENT } from './constants';
|
|
2
|
+
import type { Editor } from 'slate';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
4
|
export type LinkElement = {
|
|
5
5
|
type: typeof LINK_ELEMENT;
|
|
6
6
|
url: string;
|
|
@@ -13,7 +13,9 @@ export declare class ListsPlugin implements IPlugin {
|
|
|
13
13
|
static NUMBERED_LIST_ELEMENT: string;
|
|
14
14
|
static LIST_ITEM_ELEMENT: string;
|
|
15
15
|
constructor(options?: Options);
|
|
16
|
-
init: (editor: Editor) => import("slate").BaseEditor & import("slate-react").ReactEditor
|
|
16
|
+
init: (editor: Editor) => import("slate").BaseEditor & import("slate-react").ReactEditor & {
|
|
17
|
+
getCommands: <T extends IPlugin>(plugin: new () => T) => T["commands"];
|
|
18
|
+
};
|
|
17
19
|
blocks: {
|
|
18
20
|
type: string;
|
|
19
21
|
render: (props: RenderElementProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -23,6 +25,10 @@ export declare class ListsPlugin implements IPlugin {
|
|
|
23
25
|
handlers: {
|
|
24
26
|
onKeyDown: (event: KeyboardEvent, editor: Editor) => true | undefined;
|
|
25
27
|
};
|
|
28
|
+
commands: {
|
|
29
|
+
toggleBulletedList: () => (editor: Editor) => void;
|
|
30
|
+
toggleNumberedList: () => (editor: Editor) => void;
|
|
31
|
+
};
|
|
26
32
|
static isListActive: (editor: Editor, type: string) => boolean;
|
|
27
33
|
static isBulletedListActive: (editor: Editor) => boolean;
|
|
28
34
|
static isNumberedListActive: (editor: Editor) => boolean;
|
|
@@ -196,6 +196,10 @@ class ListsPlugin {
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
};
|
|
199
|
+
commands = {
|
|
200
|
+
toggleBulletedList: ()=>(editor)=>ListsPlugin.toggleList(editor, ListsPlugin.BULLETED_LIST_ELEMENT),
|
|
201
|
+
toggleNumberedList: ()=>(editor)=>ListsPlugin.toggleList(editor, ListsPlugin.NUMBERED_LIST_ELEMENT)
|
|
202
|
+
};
|
|
199
203
|
static isListActive = (editor, type)=>{
|
|
200
204
|
const { selection } = editor;
|
|
201
205
|
if (!selection) return false;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Options } from './types';
|
|
1
|
+
import type { Options } from './types';
|
|
2
2
|
export declare const Menu: (props: Options) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,5 +3,5 @@ import type { Options } from './types';
|
|
|
3
3
|
export declare class MenuPlugin implements IPlugin {
|
|
4
4
|
private options;
|
|
5
5
|
constructor(options: Options);
|
|
6
|
-
ui: (params: UiParams) => string | number | bigint | boolean |
|
|
6
|
+
ui: (params: UiParams) => string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
7
7
|
}
|
|
@@ -10,6 +10,8 @@ type Options = {
|
|
|
10
10
|
export declare class NodeIdPlugin implements IPlugin<Editor, NodeIdBlock> {
|
|
11
11
|
private options;
|
|
12
12
|
constructor(options: Options);
|
|
13
|
-
init(editor: Editor): import("slate").BaseEditor & import("slate-react").ReactEditor
|
|
13
|
+
init(editor: Editor): import("slate").BaseEditor & import("slate-react").ReactEditor & {
|
|
14
|
+
getCommands: <T extends IPlugin>(plugin: new () => T) => T["commands"];
|
|
15
|
+
};
|
|
14
16
|
}
|
|
15
17
|
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Element, Node, Text } from "slate";
|
|
2
2
|
const assignId = (node, generateId)=>{
|
|
3
3
|
if (Element.isElement(node)) try {
|
|
4
|
+
if (node.nodeId) return;
|
|
4
5
|
node.nodeId = generateId();
|
|
5
|
-
node.children.forEach((n)=>
|
|
6
|
+
node.children.forEach((n)=>{
|
|
7
|
+
assignId(n, generateId);
|
|
8
|
+
});
|
|
6
9
|
} catch {}
|
|
7
10
|
};
|
|
8
11
|
class NodeIdPlugin {
|
|
@@ -19,6 +19,8 @@ export type ChangeMatch = {
|
|
|
19
19
|
export declare class ShortcutsPlugin implements IPlugin {
|
|
20
20
|
private options;
|
|
21
21
|
constructor(options: Options);
|
|
22
|
-
init(editor: Editor): import("slate").BaseEditor & import("slate-react").ReactEditor
|
|
22
|
+
init(editor: Editor): import("slate").BaseEditor & import("slate-react").ReactEditor & {
|
|
23
|
+
getCommands: <T extends IPlugin>(plugin: new () => T) => T["commands"];
|
|
24
|
+
};
|
|
23
25
|
}
|
|
24
26
|
export {};
|
|
@@ -12,7 +12,9 @@ export declare class TableOfContentsPlugin implements IPlugin {
|
|
|
12
12
|
headings: NodeEntry<CustomElement>[];
|
|
13
13
|
}>;
|
|
14
14
|
constructor(options: Options);
|
|
15
|
-
init(editor: Editor): import("slate").BaseEditor & ReactEditor
|
|
15
|
+
init(editor: Editor): import("slate").BaseEditor & ReactEditor & {
|
|
16
|
+
getCommands: <T extends IPlugin>(plugin: new () => T) => T["commands"];
|
|
17
|
+
};
|
|
16
18
|
ui(params: UiParams): import("react/jsx-runtime").JSX.Element;
|
|
17
19
|
}
|
|
18
20
|
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export interface IPlugin<TEditor extends Editor = Editor, TBlock extends CustomE
|
|
|
15
15
|
onPaste?: (event: ClipboardEvent, editor: Editor) => void;
|
|
16
16
|
};
|
|
17
17
|
decorate?: (entry: NodeEntry) => DecoratedRange[];
|
|
18
|
+
commands?: {
|
|
19
|
+
[key: string]: (editor: TEditor, ...args: any[]) => void;
|
|
20
|
+
};
|
|
18
21
|
ui?: (params: UiParams) => ReactNode;
|
|
19
22
|
}
|
|
20
23
|
export type Block<TEditor extends Editor = Editor, TBlock extends CustomElement = CustomElement> = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@use-kona/editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./src/index.ts"
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"test": "vitest run"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@biomejs/biome": "2.0.0",
|
|
25
24
|
"@rsbuild/core": "~1.4.0",
|
|
26
25
|
"@rsbuild/plugin-react": "^1.3.2",
|
|
27
26
|
"@rslib/core": "^0.10.4",
|
package/src/core/createEditor.ts
CHANGED
|
@@ -14,6 +14,8 @@ import type { Block, IPlugin } from '../types';
|
|
|
14
14
|
export const createEditor = (plugins: IPlugin[]) => () => {
|
|
15
15
|
const baseEditor = withHistory(withReact(createBaseEditor()));
|
|
16
16
|
|
|
17
|
+
const pluginsMap = new Map<new () => IPlugin, IPlugin>();
|
|
18
|
+
|
|
17
19
|
const editorWithPlugins = plugins.reduce<Editor>((editor, plugin) => {
|
|
18
20
|
if (plugin.init) {
|
|
19
21
|
return plugin.init(editor);
|
|
@@ -31,22 +33,14 @@ export const createEditor = (plugins: IPlugin[]) => () => {
|
|
|
31
33
|
deleteForward,
|
|
32
34
|
} = editorWithPlugins;
|
|
33
35
|
|
|
34
|
-
editorWithPlugins.
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (!lastElement || (lastElement as CustomElement).type !== 'paragraph') {
|
|
40
|
-
const paragraph = {
|
|
41
|
-
type: 'paragraph',
|
|
42
|
-
children: [{ text: '' }],
|
|
43
|
-
};
|
|
44
|
-
Transforms.insertNodes(editorWithPlugins, paragraph, {
|
|
45
|
-
at: [editorWithPlugins.children.length],
|
|
46
|
-
});
|
|
36
|
+
editorWithPlugins.getCommands = (plugin: new () => IPlugin) => {
|
|
37
|
+
const pluginInstance = pluginsMap.get(plugin);
|
|
38
|
+
|
|
39
|
+
if (!pluginInstance) {
|
|
40
|
+
throw new Error(`Plugin ${plugin.name} not found`);
|
|
47
41
|
}
|
|
48
42
|
|
|
49
|
-
return
|
|
43
|
+
return pluginInstance.commands;
|
|
50
44
|
};
|
|
51
45
|
|
|
52
46
|
editorWithPlugins.isVoid = (element) => {
|
|
@@ -201,16 +195,18 @@ export const createEditor = (plugins: IPlugin[]) => () => {
|
|
|
201
195
|
const nodes = Array.from(
|
|
202
196
|
Editor.nodes<CustomElement>(editorWithPlugins, {
|
|
203
197
|
at: selection,
|
|
204
|
-
match: (n) =>
|
|
205
|
-
|
|
206
|
-
|
|
198
|
+
match: (n) => {
|
|
199
|
+
return (
|
|
200
|
+
!Editor.isEditor(n) &&
|
|
201
|
+
Editor.isBlock(editorWithPlugins, n as CustomElement)
|
|
202
|
+
);
|
|
203
|
+
},
|
|
207
204
|
reverse: true,
|
|
208
205
|
mode: 'highest',
|
|
209
206
|
voids: true,
|
|
210
207
|
}),
|
|
211
208
|
);
|
|
212
209
|
|
|
213
|
-
|
|
214
210
|
for (const entry of nodes) {
|
|
215
211
|
const [node, path] = entry;
|
|
216
212
|
|
|
@@ -222,18 +218,26 @@ export const createEditor = (plugins: IPlugin[]) => () => {
|
|
|
222
218
|
const plugin = plugins.find((plugin) =>
|
|
223
219
|
plugin.blocks?.find((b) => b.type === node.type),
|
|
224
220
|
);
|
|
221
|
+
|
|
225
222
|
if (plugin) {
|
|
226
223
|
const match = plugin.blocks?.find((b) => b.type === node.type);
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
if (
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
224
|
+
|
|
225
|
+
const hasOnBeforeDelete = match?.onBeforeDelete;
|
|
226
|
+
|
|
227
|
+
if (hasOnBeforeDelete) {
|
|
228
|
+
const result = await match.onBeforeDelete!([node]);
|
|
229
|
+
|
|
230
|
+
if (result) {
|
|
231
|
+
Transforms.removeNodes(editorWithPlugins, {
|
|
232
|
+
at: path,
|
|
233
|
+
match: (n) => (n as CustomElement).type === node.type,
|
|
234
|
+
});
|
|
235
|
+
match?.onDelete?.([node]);
|
|
236
|
+
} else {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
236
239
|
} else {
|
|
240
|
+
deleteFragment(options);
|
|
237
241
|
return;
|
|
238
242
|
}
|
|
239
243
|
} else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Editor } from 'slate';
|
|
2
|
-
import { RenderElementProps } from 'slate-react';
|
|
3
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import type { Editor } from 'slate';
|
|
2
|
+
import type { RenderElementProps } from 'slate-react';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
4
|
|
|
5
5
|
export type Options = {
|
|
6
6
|
onDragEnter?: () => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Descendant, Editor, Element, Transforms } from 'slate';
|
|
1
|
+
import { type Descendant, Editor, Element, Transforms } from 'slate';
|
|
2
2
|
import { jsx } from 'slate-hyperscript';
|
|
3
3
|
import type { RenderElementProps } from 'slate-react';
|
|
4
4
|
import type { IPlugin } from '../../types';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { LinksPlugin } from './LinksPlugin';
|
|
2
|
-
export {
|
|
2
|
+
export type { OptionsMethods } from './types';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { LINK_ELEMENT } from './constants';
|
|
2
|
-
import { Editor } from 'slate';
|
|
3
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import type { LINK_ELEMENT } from './constants';
|
|
2
|
+
import type { Editor } from 'slate';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
4
|
|
|
5
5
|
export type LinkElement = {
|
|
6
6
|
type: typeof LINK_ELEMENT;
|
|
@@ -328,6 +328,15 @@ export class ListsPlugin implements IPlugin {
|
|
|
328
328
|
},
|
|
329
329
|
};
|
|
330
330
|
|
|
331
|
+
commands = {
|
|
332
|
+
toggleBulletedList: () => (editor: Editor) => {
|
|
333
|
+
return ListsPlugin.toggleList(editor, ListsPlugin.BULLETED_LIST_ELEMENT);
|
|
334
|
+
},
|
|
335
|
+
toggleNumberedList: () => (editor: Editor) => {
|
|
336
|
+
return ListsPlugin.toggleList(editor, ListsPlugin.NUMBERED_LIST_ELEMENT);
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
|
|
331
340
|
static isListActive = (editor: Editor, type: string) => {
|
|
332
341
|
const { selection } = editor;
|
|
333
342
|
|
|
@@ -9,8 +9,14 @@ type NodeIdBlock = CustomElement & {
|
|
|
9
9
|
const assignId = (node: Node, generateId: () => string) => {
|
|
10
10
|
if (Element.isElement(node)) {
|
|
11
11
|
try {
|
|
12
|
+
if ((node as NodeIdBlock).nodeId) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
(node as NodeIdBlock).nodeId = generateId();
|
|
13
|
-
node.children.forEach((n) =>
|
|
17
|
+
node.children.forEach((n) => {
|
|
18
|
+
assignId(n, generateId);
|
|
19
|
+
});
|
|
14
20
|
} catch {}
|
|
15
21
|
}
|
|
16
22
|
};
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { KeyboardEvent, ReactElement, ReactNode } from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
DecoratedRange,
|
|
4
|
+
Descendant,
|
|
5
|
+
Editor,
|
|
6
|
+
NodeEntry,
|
|
7
|
+
NodeMatch,
|
|
8
|
+
} from 'slate';
|
|
3
9
|
import type { RenderElementProps, RenderLeafProps } from 'slate-react';
|
|
4
10
|
import type { CustomElement, CustomText } from '../types';
|
|
5
11
|
|
|
@@ -24,6 +30,10 @@ export interface IPlugin<
|
|
|
24
30
|
|
|
25
31
|
decorate?: (entry: NodeEntry) => DecoratedRange[];
|
|
26
32
|
|
|
33
|
+
commands?: {
|
|
34
|
+
[key: string]: (editor: TEditor, ...args: any[]) => void;
|
|
35
|
+
};
|
|
36
|
+
|
|
27
37
|
ui?: (params: UiParams) => ReactNode;
|
|
28
38
|
}
|
|
29
39
|
|