@use-kona/editor 0.1.2 → 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.
Files changed (226) hide show
  1. package/README.md +28 -17
  2. package/dist/index.d.ts +0 -1
  3. package/dist/index.js +1 -2
  4. package/dist/plugins/CodeBlockPlugin/CodeBlockPlugin.js +38 -37
  5. package/dist/plugins/CodeBlockPlugin/index.d.ts +1 -0
  6. package/dist/plugins/EmojiPlugin/EmojiPlugin.d.ts +28 -0
  7. package/dist/plugins/EmojiPlugin/EmojiPlugin.js +83 -0
  8. package/dist/plugins/EmojiPlugin/Menu.d.ts +7 -0
  9. package/dist/plugins/EmojiPlugin/Menu.js +51 -0
  10. package/dist/plugins/EmojiPlugin/index.d.ts +1 -0
  11. package/dist/plugins/EmojiPlugin/index.js +2 -0
  12. package/dist/plugins/EmojiPlugin/styles.module.js +7 -0
  13. package/dist/plugins/EmojiPlugin/styles_module.css +11 -0
  14. package/dist/plugins/EmojiPlugin/types.d.ts +7 -0
  15. package/dist/plugins/FloatingMenuPlugin/FloatingMenu.js +15 -28
  16. package/dist/plugins/FloatingMenuPlugin/types.d.ts +4 -1
  17. package/dist/plugins/HighlightsPlugin/HighlightsPlugin.d.ts +1 -0
  18. package/dist/plugins/HighlightsPlugin/HighlightsPlugin.js +3 -0
  19. package/dist/plugins/ListsPlugin/styles_module.css +4 -0
  20. package/dist/plugins/PlaceholderPlugin/PlaceholderPlugin.js +6 -3
  21. package/dist/plugins/PlaceholderPlugin/styles.module.js +1 -0
  22. package/dist/plugins/PlaceholderPlugin/styles_module.css +4 -0
  23. package/dist/plugins/index.d.ts +2 -1
  24. package/dist/plugins/index.js +2 -1
  25. package/package.json +12 -8
  26. package/src/index.ts +0 -1
  27. package/src/plugins/CodeBlockPlugin/CodeBlockPlugin.tsx +51 -48
  28. package/src/plugins/CodeBlockPlugin/index.ts +1 -0
  29. package/src/plugins/EmojiPlugin/EmojiPlugin.tsx +116 -0
  30. package/src/plugins/EmojiPlugin/Menu.tsx +74 -0
  31. package/src/plugins/EmojiPlugin/index.ts +1 -0
  32. package/src/plugins/EmojiPlugin/styles.module.css +10 -0
  33. package/src/plugins/EmojiPlugin/types.ts +5 -0
  34. package/src/plugins/FloatingMenuPlugin/FloatingMenu.tsx +13 -22
  35. package/src/plugins/FloatingMenuPlugin/types.ts +4 -1
  36. package/src/plugins/HighlightsPlugin/HighlightsPlugin.tsx +4 -0
  37. package/src/plugins/ListsPlugin/styles.module.css +4 -0
  38. package/src/plugins/PlaceholderPlugin/PlaceholderPlugin.tsx +13 -3
  39. package/src/plugins/PlaceholderPlugin/styles.module.css +2 -2
  40. package/src/plugins/index.ts +2 -1
  41. package/dist/examples/Backdrop.d.ts +0 -5
  42. package/dist/examples/Backdrop.js +0 -13
  43. package/dist/examples/Backdrop.module.js +0 -5
  44. package/dist/examples/Backdrop_module.css +0 -6
  45. package/dist/examples/CodeBlock.d.ts +0 -12
  46. package/dist/examples/CodeBlock.js +0 -163
  47. package/dist/examples/CodeBlock.module.js +0 -9
  48. package/dist/examples/CodeBlock_module.css +0 -66
  49. package/dist/examples/DragBlock.d.ts +0 -11
  50. package/dist/examples/DragBlock.js +0 -38
  51. package/dist/examples/DragBlock.module.js +0 -9
  52. package/dist/examples/DragBlock_module.css +0 -43
  53. package/dist/examples/DragHandler.d.ts +0 -2
  54. package/dist/examples/DragHandler.js +0 -44
  55. package/dist/examples/DragHandler.module.js +0 -8
  56. package/dist/examples/DragHandler_module.css +0 -18
  57. package/dist/examples/Editor.d.ts +0 -8
  58. package/dist/examples/Editor.js +0 -44
  59. package/dist/examples/Editor.module.js +0 -12
  60. package/dist/examples/Editor_module.css +0 -127
  61. package/dist/examples/FloatingMenu.d.ts +0 -17
  62. package/dist/examples/FloatingMenu.js +0 -244
  63. package/dist/examples/FloatingMenu.module.js +0 -9
  64. package/dist/examples/FloatingMenu_module.css +0 -75
  65. package/dist/examples/LinksHint.d.ts +0 -7
  66. package/dist/examples/LinksHint.js +0 -50
  67. package/dist/examples/LinksHint.module.js +0 -6
  68. package/dist/examples/LinksHint_module.css +0 -28
  69. package/dist/examples/Menu.d.ts +0 -6
  70. package/dist/examples/Menu.js +0 -79
  71. package/dist/examples/Menu.module.js +0 -8
  72. package/dist/examples/Menu_module.css +0 -38
  73. package/dist/examples/colors.d.ts +0 -10
  74. package/dist/examples/colors.js +0 -12
  75. package/dist/examples/getCommands.d.ts +0 -2
  76. package/dist/examples/getCommands.js +0 -87
  77. package/dist/examples/getPlugins.d.ts +0 -2
  78. package/dist/examples/getPlugins.js +0 -127
  79. package/dist/examples/getShortcuts.d.ts +0 -2
  80. package/dist/examples/getShortcuts.js +0 -90
  81. package/dist/examples/icons/bold.d.ts +0 -2
  82. package/dist/examples/icons/bold.js +0 -27
  83. package/dist/examples/icons/check.d.ts +0 -2
  84. package/dist/examples/icons/check.js +0 -24
  85. package/dist/examples/icons/chevronRight.d.ts +0 -2
  86. package/dist/examples/icons/chevronRight.js +0 -24
  87. package/dist/examples/icons/color.d.ts +0 -2
  88. package/dist/examples/icons/color.js +0 -30
  89. package/dist/examples/icons/copy.d.ts +0 -2
  90. package/dist/examples/icons/copy.js +0 -27
  91. package/dist/examples/icons/cross.d.ts +0 -2
  92. package/dist/examples/icons/cross.js +0 -27
  93. package/dist/examples/icons/drag.d.ts +0 -2
  94. package/dist/examples/icons/drag.js +0 -39
  95. package/dist/examples/icons/edit.d.ts +0 -2
  96. package/dist/examples/icons/edit.js +0 -30
  97. package/dist/examples/icons/external.d.ts +0 -2
  98. package/dist/examples/icons/external.js +0 -30
  99. package/dist/examples/icons/heading1.d.ts +0 -2
  100. package/dist/examples/icons/heading1.js +0 -45
  101. package/dist/examples/icons/heading2.d.ts +0 -2
  102. package/dist/examples/icons/heading2.js +0 -45
  103. package/dist/examples/icons/heading3.d.ts +0 -2
  104. package/dist/examples/icons/heading3.js +0 -48
  105. package/dist/examples/icons/italic.d.ts +0 -2
  106. package/dist/examples/icons/italic.js +0 -30
  107. package/dist/examples/icons/link.d.ts +0 -2
  108. package/dist/examples/icons/link.js +0 -30
  109. package/dist/examples/icons/ol.d.ts +0 -2
  110. package/dist/examples/icons/ol.js +0 -36
  111. package/dist/examples/icons/strikethrough.d.ts +0 -2
  112. package/dist/examples/icons/strikethrough.js +0 -27
  113. package/dist/examples/icons/text.d.ts +0 -2
  114. package/dist/examples/icons/text.js +0 -22
  115. package/dist/examples/icons/types.d.ts +0 -3
  116. package/dist/examples/icons/ul.d.ts +0 -2
  117. package/dist/examples/icons/ul.js +0 -39
  118. package/dist/examples/icons/underline.d.ts +0 -2
  119. package/dist/examples/icons/underline.js +0 -27
  120. package/dist/examples/store.d.ts +0 -8
  121. package/dist/examples/store.js +0 -6
  122. package/dist/examples/styles.module.js +0 -11
  123. package/dist/examples/styles_module.css +0 -78
  124. package/dist/examples/text.d.ts +0 -3
  125. package/dist/examples/text.js +0 -60
  126. package/dist/examples/ui/Button/Button.d.ts +0 -8
  127. package/dist/examples/ui/Button/Button.js +0 -15
  128. package/dist/examples/ui/Button/ButtonWrapper.d.ts +0 -4
  129. package/dist/examples/ui/Button/ButtonWrapper.js +0 -14
  130. package/dist/examples/ui/Button/index.d.ts +0 -2
  131. package/dist/examples/ui/Button/index.js +0 -3
  132. package/dist/examples/ui/Button/styles.module.js +0 -10
  133. package/dist/examples/ui/Button/styles_module.css +0 -72
  134. package/dist/examples/ui/Button/types.d.ts +0 -1
  135. package/dist/examples/ui/Button/types.js +0 -0
  136. package/dist/examples/ui/Dropdown/Dropdown.d.ts +0 -16
  137. package/dist/examples/ui/Dropdown/Dropdown.js +0 -75
  138. package/dist/examples/ui/Dropdown/index.d.ts +0 -1
  139. package/dist/examples/ui/Dropdown/index.js +0 -2
  140. package/dist/examples/ui/Menu/Menu.d.ts +0 -41
  141. package/dist/examples/ui/Menu/Menu.js +0 -404
  142. package/dist/examples/ui/Menu/MenuDelimiter.d.ts +0 -1
  143. package/dist/examples/ui/Menu/MenuDelimiter.js +0 -6
  144. package/dist/examples/ui/Menu/MenuHotkey.d.ts +0 -6
  145. package/dist/examples/ui/Menu/MenuHotkey.js +0 -12
  146. package/dist/examples/ui/Menu/MenuIcon.d.ts +0 -6
  147. package/dist/examples/ui/Menu/MenuIcon.js +0 -12
  148. package/dist/examples/ui/Menu/MenuItem.d.ts +0 -6
  149. package/dist/examples/ui/Menu/MenuItem.js +0 -17
  150. package/dist/examples/ui/Menu/MenuTitle.d.ts +0 -6
  151. package/dist/examples/ui/Menu/MenuTitle.js +0 -12
  152. package/dist/examples/ui/Menu/SafeSpace.d.ts +0 -6
  153. package/dist/examples/ui/Menu/SafeSpace.js +0 -65
  154. package/dist/examples/ui/Menu/index.d.ts +0 -2
  155. package/dist/examples/ui/Menu/index.js +0 -2
  156. package/dist/examples/ui/Menu/styles.module.js +0 -21
  157. package/dist/examples/ui/Menu/styles_module.css +0 -140
  158. package/dist/examples/ui/Menu/types.d.ts +0 -16
  159. package/dist/examples/ui/Menu/types.js +0 -0
  160. package/dist/examples/ui/useMenuPosition.d.ts +0 -18
  161. package/dist/examples/ui/useMenuPosition.js +0 -51
  162. package/dist/examples/ui/useMergeRefs.d.ts +0 -23
  163. package/dist/examples/ui/useMergeRefs.js +0 -11
  164. package/src/examples/Backdrop.module.css +0 -8
  165. package/src/examples/Backdrop.tsx +0 -16
  166. package/src/examples/CodeBlock.module.css +0 -65
  167. package/src/examples/CodeBlock.tsx +0 -109
  168. package/src/examples/DragBlock.module.css +0 -42
  169. package/src/examples/DragBlock.tsx +0 -57
  170. package/src/examples/DragHandler.module.css +0 -17
  171. package/src/examples/DragHandler.tsx +0 -39
  172. package/src/examples/Editor.module.css +0 -129
  173. package/src/examples/Editor.tsx +0 -68
  174. package/src/examples/FloatingMenu.module.css +0 -74
  175. package/src/examples/FloatingMenu.tsx +0 -274
  176. package/src/examples/LinksHint.module.css +0 -27
  177. package/src/examples/LinksHint.tsx +0 -58
  178. package/src/examples/Menu.module.css +0 -37
  179. package/src/examples/Menu.tsx +0 -80
  180. package/src/examples/colors.ts +0 -11
  181. package/src/examples/getCommands.tsx +0 -76
  182. package/src/examples/getPlugins.tsx +0 -143
  183. package/src/examples/getShortcuts.ts +0 -107
  184. package/src/examples/icons/bold.tsx +0 -20
  185. package/src/examples/icons/check.tsx +0 -19
  186. package/src/examples/icons/chevronRight.tsx +0 -19
  187. package/src/examples/icons/color.tsx +0 -23
  188. package/src/examples/icons/copy.tsx +0 -20
  189. package/src/examples/icons/cross.tsx +0 -20
  190. package/src/examples/icons/drag.tsx +0 -24
  191. package/src/examples/icons/edit.tsx +0 -21
  192. package/src/examples/icons/external.tsx +0 -21
  193. package/src/examples/icons/heading1.tsx +0 -26
  194. package/src/examples/icons/heading2.tsx +0 -26
  195. package/src/examples/icons/heading3.tsx +0 -27
  196. package/src/examples/icons/italic.tsx +0 -21
  197. package/src/examples/icons/link.tsx +0 -21
  198. package/src/examples/icons/ol.tsx +0 -23
  199. package/src/examples/icons/strikethrough.tsx +0 -20
  200. package/src/examples/icons/text.tsx +0 -18
  201. package/src/examples/icons/types.ts +0 -3
  202. package/src/examples/icons/ul.tsx +0 -24
  203. package/src/examples/icons/underline.tsx +0 -20
  204. package/src/examples/store.ts +0 -14
  205. package/src/examples/styles.module.css +0 -77
  206. package/src/examples/text.tsx +0 -133
  207. package/src/examples/ui/Button/Button.tsx +0 -34
  208. package/src/examples/ui/Button/ButtonWrapper.tsx +0 -22
  209. package/src/examples/ui/Button/index.ts +0 -2
  210. package/src/examples/ui/Button/styles.module.css +0 -75
  211. package/src/examples/ui/Button/types.ts +0 -1
  212. package/src/examples/ui/Dropdown/Dropdown.tsx +0 -101
  213. package/src/examples/ui/Dropdown/index.ts +0 -1
  214. package/src/examples/ui/Menu/Menu.tsx +0 -576
  215. package/src/examples/ui/Menu/MenuDelimiter.tsx +0 -3
  216. package/src/examples/ui/Menu/MenuHotkey.tsx +0 -17
  217. package/src/examples/ui/Menu/MenuIcon.tsx +0 -17
  218. package/src/examples/ui/Menu/MenuItem.tsx +0 -45
  219. package/src/examples/ui/Menu/MenuTitle.tsx +0 -17
  220. package/src/examples/ui/Menu/SafeSpace.tsx +0 -84
  221. package/src/examples/ui/Menu/index.ts +0 -2
  222. package/src/examples/ui/Menu/styles.module.css +0 -143
  223. package/src/examples/ui/Menu/types.ts +0 -18
  224. package/src/examples/ui/useMenuPosition.ts +0 -72
  225. package/src/examples/ui/useMergeRefs.ts +0 -39
  226. /package/dist/{examples/icons → plugins/EmojiPlugin}/types.js +0 -0
package/README.md CHANGED
@@ -1,23 +1,34 @@
1
- # Rslib project
1
+ # Kona Editor
2
2
 
3
- ## Setup
4
-
5
- Install the dependencies:
6
-
7
- ```bash
8
- pnpm install
9
- ```
10
-
11
- ## Get started
12
-
13
- Build the library:
3
+ ## Installing
14
4
 
15
5
  ```bash
16
- pnpm build
6
+ npm install @use-kona/editor
17
7
  ```
18
8
 
19
- Build the library in watch mode:
20
-
21
- ```bash
22
- pnpm dev
9
+ ## Using
10
+
11
+ ```tsx
12
+ import {
13
+ KonaEditor,
14
+ BasicFormattingPlugin,
15
+ /* rest of the plugins */
16
+ } from "@use-kona/editor";
17
+
18
+ const defaultValue = [
19
+ { type: 'paragraph', children: [{ text: '' }]}
20
+ ];
21
+
22
+ export const Editor = () => {
23
+ return (
24
+ <KonaEditor
25
+ plugins={[
26
+ new BasicFormattingPlugin(),
27
+ // rest of the plugins
28
+ ]}
29
+ initialValue={defaultValue}
30
+ onChange={console.log}
31
+ />
32
+ )
33
+ }
23
34
  ```
package/dist/index.d.ts CHANGED
@@ -3,7 +3,6 @@ export { deserialize } from './core/deserialize';
3
3
  export { serialize } from './core/serialize';
4
4
  export { defaultValue } from './defaultValue';
5
5
  export * from './editor';
6
- export { ExampleEditor } from './examples/Editor';
7
6
  export * from './plugins';
8
7
  export type { EditorRef, IPlugin } from './types';
9
8
  export { isEmpty } from './utils';
package/dist/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { deserialize } from "./core/deserialize.js";
2
2
  import { serialize } from "./core/serialize.js";
3
3
  import { defaultValue } from "./defaultValue.js";
4
- import { ExampleEditor } from "./examples/Editor.js";
5
4
  import { isEmpty } from "./utils.js";
6
5
  export * from "./editor.js";
7
6
  export * from "./plugins/index.js";
8
- export { ExampleEditor, defaultValue, deserialize, isEmpty, serialize };
7
+ export { defaultValue, deserialize, isEmpty, serialize };
@@ -185,44 +185,45 @@ class CodeBlockPlugin {
185
185
  return !!match;
186
186
  }
187
187
  static toggleCodeBlock = (editor)=>{
188
- Editor.withoutNormalizing(editor, ()=>{
189
- const node = Editor.above(editor, {
190
- match: (n)=>!Editor.isEditor(n) && n.type === CodeBlockPlugin.CODE_ELEMENT,
191
- mode: 'highest'
192
- });
193
- if (node) {
194
- Transforms.setNodes(editor, {
195
- type: 'paragraph'
196
- }, {
197
- at: node[1],
198
- match: (n)=>n.type === CodeBlockPlugin.CODE_LINE_ELEMENT,
199
- mode: 'lowest'
200
- });
201
- Transforms.unwrapNodes(editor, {
202
- at: node[1],
203
- match: (n)=>n.type === CodeBlockPlugin.CODE_ELEMENT,
204
- split: true
205
- });
206
- } else {
207
- Transforms.setNodes(editor, {
208
- type: CodeBlockPlugin.CODE_LINE_ELEMENT,
209
- children: [
210
- {
211
- text: ''
212
- }
213
- ]
214
- }, {
215
- match: (n)=>Editor.isBlock(editor, n) && 'paragraph' === n.type
216
- });
217
- Transforms.wrapNodes(editor, {
218
- type: CodeBlockPlugin.CODE_ELEMENT,
219
- language: "javascript",
220
- children: []
221
- }, {
222
- match: (n)=>n.type === CodeBlockPlugin.CODE_LINE_ELEMENT
223
- });
224
- }
188
+ if (!editor.selection) return;
189
+ const node = Editor.above(editor, {
190
+ match: (n)=>!Editor.isEditor(n) && n.type === CodeBlockPlugin.CODE_ELEMENT,
191
+ mode: 'highest'
225
192
  });
193
+ if (node) {
194
+ Transforms.setNodes(editor, {
195
+ type: 'paragraph'
196
+ }, {
197
+ at: node[1],
198
+ match: (n)=>n.type === CodeBlockPlugin.CODE_LINE_ELEMENT,
199
+ mode: 'lowest'
200
+ });
201
+ Transforms.unwrapNodes(editor, {
202
+ at: node[1],
203
+ match: (n)=>n.type === CodeBlockPlugin.CODE_ELEMENT,
204
+ split: true
205
+ });
206
+ } else {
207
+ Transforms.setNodes(editor, {
208
+ type: CodeBlockPlugin.CODE_LINE_ELEMENT,
209
+ children: [
210
+ {
211
+ text: ''
212
+ }
213
+ ]
214
+ }, {
215
+ mode: 'lowest'
216
+ });
217
+ Transforms.wrapNodes(editor, {
218
+ type: CodeBlockPlugin.CODE_ELEMENT,
219
+ language: "javascript",
220
+ children: []
221
+ }, {
222
+ mode: 'highest',
223
+ match: (n)=>n.type === CodeBlockPlugin.CODE_LINE_ELEMENT,
224
+ at: editor.selection.focus
225
+ });
226
+ }
226
227
  };
227
228
  }
228
229
  export { CodeBlockPlugin };
@@ -1 +1,2 @@
1
1
  export { CodeBlockPlugin } from './CodeBlockPlugin';
2
+ export type { CodeElement } from './types';
@@ -0,0 +1,28 @@
1
+ import { type MapStore } from 'nanostores';
2
+ import type { ReactNode } from 'react';
3
+ import { Editor } from 'slate';
4
+ import type { IPlugin } from '../../types';
5
+ type Options = {
6
+ onSearch: (query: string) => void;
7
+ renderMenu: (actions: {
8
+ insertEmoji: (emoji: string, query: string, editor: Editor) => void;
9
+ }) => ReactNode;
10
+ renderEmoji: (emoji: string) => ReactNode;
11
+ ignoreNodes?: string[];
12
+ };
13
+ export declare class EmojiPlugin implements IPlugin {
14
+ options: Options;
15
+ $store: MapStore<{
16
+ isOpen: boolean;
17
+ }>;
18
+ constructor(options: Options);
19
+ blocks: {
20
+ isInline: boolean;
21
+ isVoid: boolean;
22
+ type: string;
23
+ render: (props: any) => import("react/jsx-runtime").JSX.Element;
24
+ }[];
25
+ init(editor: any): any;
26
+ ui(): import("react/jsx-runtime").JSX.Element | null;
27
+ }
28
+ export {};
@@ -0,0 +1,83 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useStore } from "@nanostores/react";
3
+ import { map } from "nanostores";
4
+ import { Editor, Node, Transforms } from "slate";
5
+ import { Menu } from "./Menu.js";
6
+ import styles_module from "./styles.module.js";
7
+ class EmojiPlugin {
8
+ options;
9
+ $store;
10
+ constructor(options){
11
+ this.options = options;
12
+ this.$store = map({
13
+ isOpen: false
14
+ });
15
+ }
16
+ blocks = [
17
+ {
18
+ isInline: true,
19
+ isVoid: true,
20
+ type: 'emoji',
21
+ render: (props)=>{
22
+ const children = this.options.renderEmoji(props.element.emoji);
23
+ return /*#__PURE__*/ jsx("span", {
24
+ ...props.attributes,
25
+ className: styles_module.emojiRoot,
26
+ children: children
27
+ });
28
+ }
29
+ }
30
+ ];
31
+ init(editor) {
32
+ const { insertText, onChange } = editor;
33
+ editor.insertText = (text)=>{
34
+ if (':' === text) this.$store.setKey('isOpen', true);
35
+ insertText(text);
36
+ };
37
+ editor.onChange = (...args)=>{
38
+ if (this.$store.get().isOpen) {
39
+ const query = /:([^:]*$)/.exec(getCurrentText(editor));
40
+ if (query?.[0]) this.options.onSearch(query[1]);
41
+ else this.$store.setKey('isOpen', false);
42
+ }
43
+ return onChange(...args);
44
+ };
45
+ return editor;
46
+ }
47
+ ui() {
48
+ const { isOpen } = useStore(this.$store);
49
+ if (!isOpen) return null;
50
+ return /*#__PURE__*/ jsx(Menu, {
51
+ isOpen: isOpen,
52
+ children: this.options.renderMenu({
53
+ insertEmoji: (emoji, query, editor)=>{
54
+ this.$store.setKey('isOpen', false);
55
+ Transforms["delete"](editor, {
56
+ at: editor.selection?.focus,
57
+ distance: query.length + 1,
58
+ reverse: true,
59
+ unit: 'character'
60
+ });
61
+ Transforms.insertNodes(editor, {
62
+ type: 'emoji',
63
+ emoji,
64
+ children: [
65
+ {
66
+ text: ''
67
+ }
68
+ ]
69
+ });
70
+ Transforms.move(editor);
71
+ }
72
+ })
73
+ });
74
+ }
75
+ }
76
+ const getCurrentText = (editor)=>{
77
+ const entry = Editor.above(editor, {
78
+ match: (n)=>Editor.isBlock(editor, n)
79
+ });
80
+ if (entry) return Node.string(entry[0]);
81
+ return '';
82
+ };
83
+ export { EmojiPlugin };
@@ -0,0 +1,7 @@
1
+ import { type ReactNode } from 'react';
2
+ type Props = {
3
+ isOpen: boolean;
4
+ children: ReactNode;
5
+ };
6
+ export declare const Menu: (props: Props) => import("react").ReactPortal;
7
+ export {};
@@ -0,0 +1,51 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useLayoutEffect, useState } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { useFocused, useSlateSelection } from "slate-react";
5
+ import styles_module from "./styles.module.js";
6
+ const Menu = (props)=>{
7
+ const { isOpen, children } = props;
8
+ const isFocused = useFocused();
9
+ const selection = useSlateSelection();
10
+ const [style, setStyle] = useState({});
11
+ useLayoutEffect(()=>{
12
+ if (!selection || !isFocused) return void setStyle(void 0);
13
+ setTimeout(()=>{
14
+ const domSelection = window.getSelection();
15
+ const domRange = domSelection?.getRangeAt(0);
16
+ const rect = domRange?.getBoundingClientRect();
17
+ isOpen ? setStyle({
18
+ opacity: 1,
19
+ transform: 'scale(1)',
20
+ top: `${(rect?.top || 0) + window.scrollY + (rect?.height || 0) + 2}px`,
21
+ left: `${(rect?.left || 0) + window.scrollX + (rect?.width || 0) / 2}px`
22
+ }) : setStyle({
23
+ opacity: 0,
24
+ transform: 'scale(0.9)'
25
+ });
26
+ }, 0);
27
+ }, [
28
+ selection,
29
+ isFocused,
30
+ isOpen
31
+ ]);
32
+ const handleMenuLayout = (element)=>{
33
+ if (element) {
34
+ const { height, top } = element.getBoundingClientRect();
35
+ const domSelection = window.getSelection();
36
+ const domRange = domSelection?.getRangeAt(0);
37
+ const rect = domRange?.getBoundingClientRect();
38
+ if (top + height >= window.innerHeight) setStyle((style)=>({
39
+ ...style,
40
+ top: `${top - height - (rect?.height ?? 22)}px`
41
+ }));
42
+ }
43
+ };
44
+ return /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx("div", {
45
+ ref: handleMenuLayout,
46
+ style: style,
47
+ className: styles_module.root,
48
+ children: children
49
+ }), document.body);
50
+ };
51
+ export { Menu };
@@ -0,0 +1 @@
1
+ export { EmojiPlugin } from './EmojiPlugin';
@@ -0,0 +1,2 @@
1
+ import { EmojiPlugin } from "./EmojiPlugin.js";
2
+ export { EmojiPlugin };
@@ -0,0 +1,7 @@
1
+ import "./styles_module.css";
2
+ const styles_module = {
3
+ root: "root-LWInsU",
4
+ "emoji-root": "emoji-root-rs2hSK",
5
+ emojiRoot: "emoji-root-rs2hSK"
6
+ };
7
+ export { styles_module as default };
@@ -0,0 +1,11 @@
1
+ .root-LWInsU {
2
+ z-index: 2;
3
+ position: absolute;
4
+ }
5
+
6
+ .emoji-root-rs2hSK {
7
+ vertical-align: text-bottom;
8
+ height: 24px;
9
+ display: inline-flex;
10
+ }
11
+
@@ -0,0 +1,7 @@
1
+ export type EmojiElement = {
2
+ type: 'emoji';
3
+ emoji: string;
4
+ children: [{
5
+ text: string;
6
+ }];
7
+ };
@@ -1,4 +1,4 @@
1
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
1
+ import { jsx } from "react/jsx-runtime";
2
2
  import { useLayoutEffect, useRef, useState } from "react";
3
3
  import { createPortal } from "react-dom";
4
4
  import { Editor, Range } from "slate";
@@ -57,33 +57,20 @@ const FloatingMenu = (props)=>{
57
57
  });
58
58
  };
59
59
  if (!isVisible) return null;
60
- return /*#__PURE__*/ createPortal(/*#__PURE__*/ jsxs(Fragment, {
61
- children: [
62
- /*#__PURE__*/ jsx("div", {
63
- onMouseDown: ()=>{
64
- setStyle(void 0);
65
- },
66
- children: options.renderBackdrop?.({
67
- onClose,
68
- onUpdate: handleUpdate
69
- })
70
- }),
71
- /*#__PURE__*/ jsx("div", {
72
- ref: ref,
73
- style: {
74
- ...style,
75
- display: 'block'
76
- },
77
- className: styles_module.root,
78
- onMouseDown: (event)=>{
79
- event.preventDefault();
80
- },
81
- children: options.renderMenu(editor, {
82
- onClose,
83
- onUpdate: handleUpdate
84
- })
85
- })
86
- ]
60
+ return /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx("div", {
61
+ ref: ref,
62
+ style: {
63
+ ...style,
64
+ display: 'block'
65
+ },
66
+ className: styles_module.root,
67
+ onMouseDown: (event)=>{
68
+ event.preventDefault();
69
+ },
70
+ children: options.renderMenu(editor, {
71
+ onClose,
72
+ onUpdate: handleUpdate
73
+ })
87
74
  }), document.body);
88
75
  };
89
76
  export { FloatingMenu };
@@ -3,7 +3,10 @@ import type { Editor } from 'slate';
3
3
  export type Options = {
4
4
  ignoreNodes?: string[];
5
5
  renderMenu: (editor: Editor, commands: Commands) => ReactNode;
6
- renderBackdrop: (commands: {
6
+ /**
7
+ * @deprecated
8
+ */
9
+ renderBackdrop?: (commands: {
7
10
  onClose: () => void;
8
11
  onUpdate: () => void;
9
12
  }) => ReactNode;
@@ -9,6 +9,7 @@ export declare class HighlightsPlugin implements IPlugin {
9
9
  constructor(options: Options);
10
10
  static toggleHighlight(editor: Editor, color: string): void;
11
11
  static isHighlightActive(editor: Editor, color: string): boolean;
12
+ static removeHighlight(editor: Editor): void;
12
13
  leafs: {
13
14
  render: (props: RenderLeafProps) => import("react/jsx-runtime").JSX.Element;
14
15
  }[];
@@ -14,6 +14,9 @@ class HighlightsPlugin {
14
14
  const marks = Editor.marks(editor);
15
15
  return marks ? marks.highlight === color : false;
16
16
  }
17
+ static removeHighlight(editor) {
18
+ Editor.removeMark(editor, 'highlight');
19
+ }
17
20
  leafs = [
18
21
  {
19
22
  render: (props)=>{
@@ -1,5 +1,9 @@
1
1
  .list-YEmg4D {
2
2
  padding: 0;
3
+
4
+ & & {
5
+ margin-left: 32px;
6
+ }
3
7
  }
4
8
 
5
9
  .listItem-lLiZlv {
@@ -14,7 +14,9 @@ class PlaceholderPlugin {
14
14
  const isReadOnly = useReadOnly();
15
15
  const isFocused = useFocused();
16
16
  const entity = Editor.above(editor, {
17
- mode: 'lowest'
17
+ at: editor.selection?.focus,
18
+ mode: 'lowest',
19
+ voids: true
18
20
  });
19
21
  const firstEntity = Editor.above(editor, {
20
22
  mode: 'lowest',
@@ -24,14 +26,15 @@ class PlaceholderPlugin {
24
26
  ]
25
27
  });
26
28
  if (entity && this.options.ignoreNodes?.includes(entity[0].type)) return props.children;
27
- const isEmpty = !entity || '' === Node.string(entity[0]);
29
+ const hasVoids = entity?.[0].children.some((n)=>Editor.isVoid(editor, n));
30
+ const isEmpty = (!entity || '' === Node.string(entity[0])) && !hasVoids && !Editor.isVoid(editor, entity?.[0]);
28
31
  const isEditorEmpty = !firstEntity || '' === Node.string(firstEntity[0]) && editor.children.length <= 1;
29
32
  const isVisible = isEmpty && !isReadOnly && isSelected || isEditorEmpty;
30
33
  return /*#__PURE__*/ jsx(Fragment, {
31
34
  children: /*#__PURE__*/ jsx("span", {
32
35
  ...props.attributes,
33
36
  children: /*#__PURE__*/ jsx("span", {
34
- className: isVisible ? styles_module.placeholder : void 0,
37
+ className: isVisible ? styles_module.placeholder : styles_module.hidden,
35
38
  "data-placeholder": isFocused ? this.options.focused : this.options.unfocused,
36
39
  children: props.children
37
40
  })
@@ -1,5 +1,6 @@
1
1
  import "./styles_module.css";
2
2
  const styles_module = {
3
+ hidden: "hidden-vT5wYn",
3
4
  placeholder: "placeholder-F_8jdT"
4
5
  };
5
6
  export { styles_module as default };
@@ -1,3 +1,7 @@
1
+ .hidden-vT5wYn.placeholder-F_8jdT {
2
+ display: none;
3
+ }
4
+
1
5
  .placeholder-F_8jdT {
2
6
  position: relative;
3
7
  }
@@ -1,9 +1,10 @@
1
1
  export { AttachmentsPlugin } from './AttachmentsPlugin';
2
2
  export { BasicFormattingPlugin } from './BasicFormattingPlugin';
3
3
  export { BreaksPlugin } from './BreaksPlugin';
4
- export { CodeBlockPlugin } from './CodeBlockPlugin';
4
+ export { CodeBlockPlugin, type CodeElement } from './CodeBlockPlugin';
5
5
  export { type Command, CommandsPlugin } from './CommandsPlugin';
6
6
  export { DnDPlugin } from './DnDPlugin';
7
+ export { EmojiPlugin } from './EmojiPlugin';
7
8
  export { type Commands, FloatingMenuPlugin } from './FloatingMenuPlugin';
8
9
  export { HeadingsPlugin } from './HeadingsPlugin';
9
10
  export { HighlightsPlugin } from './HighlightsPlugin';
@@ -4,6 +4,7 @@ import { BreaksPlugin } from "./BreaksPlugin/index.js";
4
4
  import { CodeBlockPlugin } from "./CodeBlockPlugin/index.js";
5
5
  import { CommandsPlugin } from "./CommandsPlugin/index.js";
6
6
  import { DnDPlugin } from "./DnDPlugin/index.js";
7
+ import { EmojiPlugin } from "./EmojiPlugin/index.js";
7
8
  import { FloatingMenuPlugin } from "./FloatingMenuPlugin/index.js";
8
9
  import { HeadingsPlugin } from "./HeadingsPlugin/index.js";
9
10
  import { HighlightsPlugin } from "./HighlightsPlugin/index.js";
@@ -14,4 +15,4 @@ import { NodeIdPlugin } from "./NodeIdPlugin/index.js";
14
15
  import { PlaceholderPlugin } from "./PlaceholderPlugin/index.js";
15
16
  import { ShortcutsPlugin } from "./ShortcutsPlugin/index.js";
16
17
  import { TableOfContentsPlugin } from "./TableOfContentsPlugin/index.js";
17
- export { AttachmentsPlugin, BasicFormattingPlugin, BreaksPlugin, CodeBlockPlugin, CommandsPlugin, DnDPlugin, FloatingMenuPlugin, HeadingsPlugin, HighlightsPlugin, LinksPlugin, ListsPlugin, MenuPlugin, NodeIdPlugin, PlaceholderPlugin, ShortcutsPlugin, TableOfContentsPlugin };
18
+ export { AttachmentsPlugin, BasicFormattingPlugin, BreaksPlugin, CodeBlockPlugin, CommandsPlugin, DnDPlugin, EmojiPlugin, FloatingMenuPlugin, HeadingsPlugin, HighlightsPlugin, LinksPlugin, ListsPlugin, MenuPlugin, NodeIdPlugin, PlaceholderPlugin, ShortcutsPlugin, TableOfContentsPlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@use-kona/editor",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/index.ts"
@@ -48,13 +48,21 @@
48
48
  "storybook-addon-rslib": "^2.0.2",
49
49
  "storybook-react-rsbuild": "^2.0.2",
50
50
  "typescript": "^5.8.3",
51
- "vitest": "^3.2.4"
51
+ "vitest": "^3.2.4",
52
+ "slate": "^0.117.2",
53
+ "slate-history": "^0.113.1",
54
+ "slate-hyperscript": "^0.100.0",
55
+ "slate-react": "^0.117.3"
52
56
  },
53
57
  "peerDependencies": {
54
58
  "react": ">=16.9.0",
55
59
  "react-dnd": "^16.0.1",
56
60
  "react-dnd-html5-backend": "^16.0.1",
57
- "react-dom": "18"
61
+ "react-dom": "18",
62
+ "slate": "^0.117.2",
63
+ "slate-history": "^0.113.1",
64
+ "slate-hyperscript": "^0.100.0",
65
+ "slate-react": "^0.117.3"
58
66
  },
59
67
  "dependencies": {
60
68
  "@nanostores/react": "^1.0.0",
@@ -63,10 +71,6 @@
63
71
  "is-hotkey": "^0.2.0",
64
72
  "is-url": "^1.2.4",
65
73
  "nanostores": "^1.0.1",
66
- "prismjs": "^1.30.0",
67
- "slate": "^0.117.2",
68
- "slate-history": "^0.113.1",
69
- "slate-hyperscript": "^0.100.0",
70
- "slate-react": "^0.117.3"
74
+ "prismjs": "^1.30.0"
71
75
  }
72
76
  }
package/src/index.ts CHANGED
@@ -3,7 +3,6 @@ export { deserialize } from './core/deserialize';
3
3
  export { serialize } from './core/serialize';
4
4
  export { defaultValue } from './defaultValue';
5
5
  export * from './editor';
6
- export { ExampleEditor } from './examples/Editor';
7
6
  export * from './plugins';
8
7
  export type { EditorRef, IPlugin } from './types';
9
8
  export { isEmpty } from './utils';