Skip to content

Commit 0252e4b

Browse files
committed
docs wip
1 parent cb3c1d8 commit 0252e4b

File tree

11 files changed

+347
-5
lines changed

11 files changed

+347
-5
lines changed

apps/site/docs/guide/plugins/_meta.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,12 @@
66
"dnd-plugin/index",
77
"floating-menu-plugin/index",
88
"headings-plugin/index",
9-
"highlights-plugin/index"
9+
"highlights-plugin/index",
10+
"links-plugin/index",
11+
"lists-plugin/index",
12+
"menu-plugin/index",
13+
"node-id-plugin/index",
14+
"placeholder-plugin/index",
15+
"shortcuts-plugin/index",
16+
"table-of-contents-plugin/index"
1017
]

apps/site/docs/guide/plugins/highlights-plugin/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const colors = {
2626

2727

2828
const highlightsPlugin = new HighlightsPlugin({
29-
color,
29+
colors,
3030
});
3131

3232
return (
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
title: LinksPlugin
3+
---
4+
import { Tab, Tabs } from 'rspress/theme';
5+
6+
## Description
7+
Allows adding links to the selected text.
8+
9+
10+
## Usage
11+
### Example
12+
Work in progress.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: ListsPlugin
3+
---
4+
5+
## Description
6+
It allows adding numbered and bulleted lists to the editor. Also controls indenting list items.
7+
8+
9+
## Usage
10+
### Example
11+
```tsx
12+
import { KonaEditor, ListsPlugin } from "@kona/editor";
13+
14+
const listsPlugin = new ListsPlugin();
15+
16+
return (
17+
<KonaEditor plugins={[listsPlugin]} />
18+
)
19+
```
20+
21+
### Static methods
22+
#### `ListsPlugin.toggleList(editor, listType)`
23+
Converts the current node to the list of a particular type.
24+
25+
#### `ListsPlugin.isListActive(editor, listType)`
26+
Checks if the currently selected node is a list of a particular type.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
title: HeadingsPlugin
3+
---
4+
5+
import { Tabs, Tab } from "rspress/theme";
6+
7+
## Description
8+
This plugin adds a sticky menu to the top of the editor where you can place controls for changing
9+
the current block
10+
11+
12+
## Usage
13+
### Example
14+
<Tabs>
15+
<Tab label="Editor.tsx">
16+
```tsx
17+
import { KonaEditor, MenuPlugin } from "@kona/editor";
18+
19+
const menuPlugin = new MenuPlugin({
20+
renderMenu: ({ editor }) => {
21+
return <Menu editor={editor} />;
22+
}
23+
});
24+
25+
return (
26+
<KonaEditor plugins={[menuPlugin]} />
27+
)
28+
```
29+
</Tab>
30+
<Tab label="Menu.tsx">
31+
```tsx
32+
type Props = {
33+
editor: Editor;
34+
}
35+
36+
const getButtonClassName = (isActive: boolean) => {
37+
return isActive ? [styles.button, styles.active].join(' ') : styles.button;
38+
};
39+
40+
export const Menu = (props: Props) => {
41+
const { editor } = props;
42+
43+
return (
44+
<div>
45+
<button
46+
type="button"
47+
className={getButtonClassName(
48+
HeadingsPlugin.isHeading1Active(editor)
49+
)}
50+
onMouseDown={(event) => {
51+
event.preventDefault();
52+
HeadingsPlugin.toggleHeading1(editor);
53+
}}
54+
>
55+
</button>
56+
</div>
57+
)
58+
}
59+
```
60+
</Tab>
61+
</Tabs>
62+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: NodeIdPlugin
3+
---
4+
5+
## Description
6+
This plugin adds a unique id for each block. I use it for keeping the reference to the block for subtasks,
7+
but now I'm not sure if this plugin is still necessary. You can safely ignore it.
8+
9+
10+
## Usage
11+
### Example
12+
13+
You have to bring your own function for generating the id. I use [nanoid](https://github.com/ai/nanoid), but
14+
simple `Math.random().toString(36).substring(2, 15)` might be fine for your needs.
15+
16+
```tsx
17+
import { KonaEditor, NodeIdPlugin } from '@kona/editor';
18+
19+
const nodeIdPlugin = new NodeIdPlugin({
20+
generateId: () => Math.random().toString(36).substring(2, 15)
21+
})
22+
23+
return (
24+
<KonaEditor plugins={[nodeIdPlugin]} />
25+
)
26+
```
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: PlaceholderPlugin
3+
---
4+
5+
## Description
6+
This plugin shows the placeholder for the current node if it is empty.
7+
8+
## Usage
9+
It has two parameters: `focused` and `unfocused` for both states of the editor. You can also
10+
provide a list of blocks where placeholder shouldn't be shown via `ignoreNodes` parameter.
11+
12+
### Example
13+
```tsx
14+
import { KonaEditor, PlaceholderPlugin, CodeBlockPlugin } from "@kona/editor";
15+
16+
const placeholderPlugin = new PlaceholderPlugin({
17+
focused: 'Write / to open command menu',
18+
unfocused: 'Add a note...',
19+
ignoreNodes: [CodeBlockPlugin.CODE_LINE_ELEMENT],
20+
});
21+
22+
return (
23+
<KonaEditor plugins={[placeholderPlugin]} />
24+
)
25+
26+
```
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: ShortcutsPlugin
3+
---
4+
5+
## Description
6+
Plugin for adding markdown shortcuts.
7+
8+
## Usage
9+
```tsx
10+
import { KonaEditor, ShortcutsPlugin, CodeBlockPlugin } from "@kona/editor";
11+
import { getShortcuts } from "./getShortcuts";
12+
13+
const shortcutsPlugin = new ShortcutsPlugin({
14+
shortcuts: getShortcuts(),
15+
ignoreNodes: [CodeBlockPlugin.CODE_LINE_ELEMENT]
16+
})
17+
```
18+
19+
I usually store shortcuts in a separate file because the list can be pretty large.
20+
The order of the shortcuts matters because the first one found will be applied and the later will be ignored.
21+
22+
```ts
23+
import { Editor, Transforms } from 'slate';
24+
import { type ChangeMatch, HeadingsPlugin, type Shortcut } from '../plugins';
25+
26+
export const getShortcuts = (): Shortcut[] => {
27+
return [
28+
{
29+
trigger: ' ',
30+
before: /\*\*/g,
31+
after: /\*\*/g,
32+
change(editor: Editor, match) {
33+
replaceWithMarkedText(editor, match, 'bold');
34+
},
35+
},
36+
{
37+
trigger: ' ',
38+
before: /\*/g,
39+
after: /\*/g,
40+
change(editor: Editor, match) {
41+
replaceWithMarkedText(editor, match, 'italic');
42+
},
43+
},
44+
{
45+
trigger: ' ',
46+
before: /~~/g,
47+
after: /~~/g,
48+
change(editor: Editor, match) {
49+
replaceWithMarkedText(editor, match, 'strikethrough');
50+
},
51+
},
52+
{
53+
trigger: ' ',
54+
before: /^###/g,
55+
change(editor, match) {
56+
replaceWithHeading(editor, match, HeadingsPlugin.HeadingLevel3);
57+
},
58+
},
59+
{
60+
trigger: ' ',
61+
before: /^##/g,
62+
change(editor, match) {
63+
replaceWithHeading(editor, match, HeadingsPlugin.HeadingLevel2);
64+
},
65+
},
66+
{
67+
trigger: ' ',
68+
before: /^#/g,
69+
change(editor, match) {
70+
replaceWithHeading(editor, match, HeadingsPlugin.HeadingLevel1);
71+
},
72+
},
73+
];
74+
};
75+
76+
const replaceWithHeading = (
77+
editor: Editor,
78+
match: ChangeMatch,
79+
type: string,
80+
) => {
81+
Editor.withoutNormalizing(editor, () => {
82+
const { selection } = editor;
83+
84+
if (selection) {
85+
Transforms.delete(editor, {
86+
at: selection.focus,
87+
distance: match.before?.[0].length,
88+
reverse: true,
89+
unit: 'character',
90+
});
91+
92+
Transforms.setNodes(editor, {
93+
type,
94+
});
95+
}
96+
});
97+
};
98+
99+
const replaceWithMarkedText = (
100+
editor: Editor,
101+
match: ChangeMatch,
102+
mark: string,
103+
) => {
104+
Editor.withoutNormalizing(editor, () => {
105+
if (!editor.selection) {
106+
return;
107+
}
108+
109+
Transforms.delete(editor, {
110+
at: editor.selection?.focus,
111+
distance: match.text?.length || 0,
112+
reverse: true,
113+
unit: 'character',
114+
});
115+
Transforms.insertText(editor, match.cleanText || '');
116+
Transforms.setSelection(editor, {
117+
anchor: editor.selection?.focus,
118+
focus: {
119+
path: editor.selection?.focus.path,
120+
offset: editor.selection?.focus.offset - (match.cleanText?.length || 0),
121+
},
122+
});
123+
Editor.addMark(editor, mark, true);
124+
Transforms.setSelection(editor, {
125+
anchor: editor.selection.anchor,
126+
focus: editor.selection.anchor,
127+
});
128+
});
129+
};
130+
131+
```
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: TableOfContentsPlugin
3+
---
4+
5+
## Description
6+
This plugin adds a sticky block with headings and a quick navigation to each.
7+
8+
## Usage
9+
### Example
10+
```tsx
11+
import { KonaEditor, TableOfContentsPlugin } from
12+
13+
const tocPlugin = new TableOfContentsPlugin({
14+
levels: {
15+
[HeadingsPlugin.HeadingLevel1]: 1,
16+
[HeadingsPlugin.HeadingLevel2]: 2,
17+
[HeadingsPlugin.HeadingLevel3]: 3,
18+
},
19+
});
20+
21+
return (
22+
<KonaEditor plugins={[tocPlugin]} />
23+
)
24+
```

apps/site/rspress.config.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,34 @@ export default defineConfig({
6565
{
6666
text: 'HighlightsPlugin',
6767
link: '/guide/plugins/highlights-plugin',
68+
},
69+
{
70+
text: 'LinksPlugin',
71+
link: '/guide/plugins/links-plugin',
72+
},
73+
{
74+
text: 'ListsPlugin',
75+
link: '/guide/plugins/lists-plugin',
76+
},
77+
{
78+
text: 'MenuPlugin',
79+
link: '/guide/plugins/menu-plugin',
80+
},
81+
{
82+
text: 'NodeIdPlugin',
83+
link: '/guide/plugins/node-id-plugin',
84+
},
85+
{
86+
text: 'PlaceholderPlugin',
87+
link: '/guide/plugins/placeholder-plugin',
88+
},
89+
{
90+
text: 'ShortcutsPlugin',
91+
link: '/guide/plugins/shortcuts-plugin',
92+
},
93+
{
94+
text: 'TableOfContentsPlugin',
95+
link: '/guide/plugins/table-of-contents-plugin',
6896
}
6997
]
7098
}

0 commit comments

Comments
 (0)