@blocknote/core 0.8.0 → 0.8.2

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 (34) hide show
  1. package/dist/blocknote.js +594 -503
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +6 -2
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/package.json +3 -3
  7. package/src/BlockNoteEditor.ts +18 -0
  8. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +292 -0
  9. package/src/api/nodeConversions/nodeConversions.test.ts +236 -0
  10. package/src/api/nodeConversions/nodeConversions.ts +166 -35
  11. package/src/editor.module.css +5 -5
  12. package/src/extensions/Blocks/nodes/Block.module.css +4 -4
  13. package/src/extensions/Blocks/nodes/BlockContainer.ts +12 -3
  14. package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +2 -2
  15. package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +59 -24
  16. package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +4 -6
  17. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +28 -35
  18. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.ts +2 -2
  19. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +38 -10
  20. package/src/shared/EditorElement.ts +3 -3
  21. package/src/shared/plugins/suggestion/SuggestionPlugin.ts +23 -17
  22. package/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts +2 -2
  23. package/types/src/BlockNoteEditor.d.ts +2 -0
  24. package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +1 -1
  25. package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +2 -2
  26. package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +2 -3
  27. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +2 -3
  28. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.d.ts +1 -1
  29. package/types/src/extensions/Placeholder/localisation/index.d.ts +2 -0
  30. package/types/src/extensions/Placeholder/localisation/translation.d.ts +51 -0
  31. package/types/src/shared/EditorElement.d.ts +3 -3
  32. package/types/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.d.ts +1 -1
  33. package/types/src/extensions/Blocks/api/alertBlock.d.ts +0 -13
  34. package/types/src/extensions/Blocks/api/alertBlock2.d.ts +0 -13
@@ -36,6 +36,8 @@ class HyperlinkToolbarView {
36
36
  hyperlinkMark: Mark | undefined;
37
37
  hyperlinkMarkRange: Range | undefined;
38
38
 
39
+ private lastPosition: DOMRect | undefined;
40
+
39
41
  constructor({ editor, hyperlinkToolbarFactory }: HyperlinkToolbarViewProps) {
40
42
  this.editor = editor;
41
43
 
@@ -57,7 +59,7 @@ class HyperlinkToolbarView {
57
59
  };
58
60
 
59
61
  this.editor.view.dom.addEventListener("mouseover", this.mouseOverHandler);
60
- document.addEventListener("scroll", this.scrollHandler);
62
+ document.addEventListener("click", this.clickHandler, true);
61
63
  }
62
64
 
63
65
  mouseOverHandler = (event: MouseEvent) => {
@@ -101,9 +103,21 @@ class HyperlinkToolbarView {
101
103
  return false;
102
104
  };
103
105
 
104
- scrollHandler = () => {
105
- if (this.hyperlinkMark !== undefined) {
106
- this.hyperlinkToolbar.render(this.getDynamicParams(), false);
106
+ clickHandler = (event: MouseEvent) => {
107
+ if (
108
+ // Toolbar is open.
109
+ this.hyperlinkMark &&
110
+ // An element is clicked.
111
+ event &&
112
+ event.target &&
113
+ // Element is outside the editor.
114
+ this.editor.view.dom !== (event.target as Node) &&
115
+ !this.editor.view.dom.contains(event.target as Node) &&
116
+ // Element is outside the toolbar.
117
+ this.hyperlinkToolbar.element !== (event.target as Node) &&
118
+ !this.hyperlinkToolbar.element?.contains(event.target as Node)
119
+ ) {
120
+ this.hyperlinkToolbar.hide();
107
121
  }
108
122
  };
109
123
 
@@ -201,7 +215,6 @@ class HyperlinkToolbarView {
201
215
  "mouseover",
202
216
  this.mouseOverHandler
203
217
  );
204
- document.removeEventListener("scroll", this.scrollHandler);
205
218
  }
206
219
 
207
220
  getStaticParams(): HyperlinkToolbarStaticParams {
@@ -236,6 +249,26 @@ class HyperlinkToolbarView {
236
249
 
237
250
  this.hyperlinkToolbar.hide();
238
251
  },
252
+ getReferenceRect: () => {
253
+ if (!this.hyperlinkMark) {
254
+ if (this.lastPosition === undefined) {
255
+ throw new Error(
256
+ "Attempted to access hyperlink reference rect before rendering hyperlink toolbar."
257
+ );
258
+ }
259
+
260
+ return this.lastPosition;
261
+ }
262
+
263
+ const hyperlinkBoundingBox = posToDOMRect(
264
+ this.editor.view,
265
+ this.hyperlinkMarkRange!.from,
266
+ this.hyperlinkMarkRange!.to
267
+ );
268
+ this.lastPosition = hyperlinkBoundingBox;
269
+
270
+ return hyperlinkBoundingBox;
271
+ },
239
272
  };
240
273
  }
241
274
 
@@ -246,11 +279,6 @@ class HyperlinkToolbarView {
246
279
  this.hyperlinkMarkRange!.from,
247
280
  this.hyperlinkMarkRange!.to
248
281
  ),
249
- referenceRect: posToDOMRect(
250
- this.editor.view,
251
- this.hyperlinkMarkRange!.from,
252
- this.hyperlinkMarkRange!.to
253
- ),
254
282
  };
255
283
  }
256
284
  }
@@ -1,7 +1,7 @@
1
- export type RequiredStaticParams = Record<string, any>;
2
- export type RequiredDynamicParams = Record<string, any> & {
3
- referenceRect: DOMRect;
1
+ export type RequiredStaticParams = Record<string, any> & {
2
+ getReferenceRect: () => DOMRect;
4
3
  };
4
+ export type RequiredDynamicParams = Record<string, any> & {};
5
5
 
6
6
  export type EditorElement<ElementDynamicParams extends RequiredDynamicParams> =
7
7
  {
@@ -107,6 +107,8 @@ class SuggestionPluginView<
107
107
  pluginState: SuggestionPluginState<T>;
108
108
  itemCallback: (item: T) => void;
109
109
 
110
+ private lastPosition: DOMRect | undefined;
111
+
110
112
  constructor({
111
113
  editor,
112
114
  pluginKey,
@@ -137,16 +139,8 @@ class SuggestionPluginView<
137
139
  };
138
140
 
139
141
  this.suggestionsMenu = suggestionsMenuFactory(this.getStaticParams());
140
-
141
- document.addEventListener("scroll", this.handleScroll);
142
142
  }
143
143
 
144
- handleScroll = () => {
145
- if (this.pluginKey.getState(this.editor._tiptapEditor.state).active) {
146
- this.suggestionsMenu.render(this.getDynamicParams(), false);
147
- }
148
- };
149
-
150
144
  update(view: EditorView, prevState: EditorState) {
151
145
  const prev = this.pluginKey.getState(prevState);
152
146
  const next = this.pluginKey.getState(view.state);
@@ -188,25 +182,37 @@ class SuggestionPluginView<
188
182
  }
189
183
  }
190
184
 
191
- destroy() {
192
- document.removeEventListener("scroll", this.handleScroll);
193
- }
194
-
195
185
  getStaticParams(): SuggestionsMenuStaticParams<T> {
196
186
  return {
197
187
  itemCallback: (item: T) => this.itemCallback(item),
188
+ getReferenceRect: () => {
189
+ const decorationNode = document.querySelector(
190
+ `[data-decoration-id="${this.pluginState.decorationId}"]`
191
+ );
192
+
193
+ if (!decorationNode) {
194
+ if (this.lastPosition === undefined) {
195
+ throw new Error(
196
+ "Attempted to access trigger character reference rect before rendering suggestions menu."
197
+ );
198
+ }
199
+
200
+ return this.lastPosition;
201
+ }
202
+
203
+ const triggerCharacterBoundingBox =
204
+ decorationNode.getBoundingClientRect();
205
+ this.lastPosition = triggerCharacterBoundingBox;
206
+
207
+ return triggerCharacterBoundingBox;
208
+ },
198
209
  };
199
210
  }
200
211
 
201
212
  getDynamicParams(): SuggestionsMenuDynamicParams<T> {
202
- const decorationNode = document.querySelector(
203
- `[data-decoration-id="${this.pluginState.decorationId}"]`
204
- );
205
-
206
213
  return {
207
214
  items: this.pluginState.items,
208
215
  keyboardHoveredItemIndex: this.pluginState.keyboardHoveredItemIndex!,
209
- referenceRect: decorationNode!.getBoundingClientRect(),
210
216
  };
211
217
  }
212
218
  }
@@ -3,13 +3,13 @@ import { SuggestionItem } from "./SuggestionItem";
3
3
 
4
4
  export type SuggestionsMenuStaticParams<T extends SuggestionItem> = {
5
5
  itemCallback: (item: T) => void;
6
+
7
+ getReferenceRect: () => DOMRect;
6
8
  };
7
9
 
8
10
  export type SuggestionsMenuDynamicParams<T extends SuggestionItem> = {
9
11
  items: T[];
10
12
  keyboardHoveredItemIndex: number;
11
-
12
- referenceRect: DOMRect;
13
13
  };
14
14
 
15
15
  export type SuggestionsMenu<T extends SuggestionItem> = EditorElement<
@@ -104,7 +104,9 @@ export declare class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockS
104
104
  };
105
105
  blockCache: WeakMap<Node, Block<BSchema>>;
106
106
  readonly schema: BSchema;
107
+ private ready;
107
108
  get domElement(): HTMLDivElement;
109
+ isFocused(): boolean;
108
110
  focus(): void;
109
111
  constructor(options?: Partial<BlockNoteEditorOptions<BSchema>>);
110
112
  /**
@@ -8,10 +8,10 @@ export type BlockSideMenuStaticParams<BSchema extends BlockSchema> = {
8
8
  blockDragEnd: () => void;
9
9
  freezeMenu: () => void;
10
10
  unfreezeMenu: () => void;
11
+ getReferenceRect: () => DOMRect;
11
12
  };
12
13
  export type BlockSideMenuDynamicParams<BSchema extends BlockSchema> = {
13
14
  block: Block<BSchema>;
14
- referenceRect: DOMRect;
15
15
  };
16
16
  export type BlockSideMenu<BSchema extends BlockSchema> = EditorElement<BlockSideMenuDynamicParams<BSchema>>;
17
17
  export type BlockSideMenuFactory<BSchema extends BlockSchema> = ElementFactory<BlockSideMenuStaticParams<BSchema>, BlockSideMenuDynamicParams<BSchema>>;
@@ -20,6 +20,7 @@ export declare class BlockMenuView<BSchema extends BlockSchema> {
20
20
  isDragging: boolean;
21
21
  menuOpen: boolean;
22
22
  menuFrozen: boolean;
23
+ private lastPosition;
23
24
  constructor({ tiptapEditor, editor, blockMenuFactory, horizontalPosAnchoredAtRoot, }: BlockMenuViewProps<BSchema>);
24
25
  /**
25
26
  * Sets isDragging when dragging text.
@@ -32,7 +33,7 @@ export declare class BlockMenuView<BSchema extends BlockSchema> {
32
33
  */
33
34
  onDrop: (event: DragEvent) => void;
34
35
  /**
35
- * If the event is outside of the editor contents,
36
+ * If the event is outside the editor contents,
36
37
  * we dispatch a fake event, so that we can still drop the content
37
38
  * when dragging / dropping to the side of the editor
38
39
  */
@@ -40,7 +41,6 @@ export declare class BlockMenuView<BSchema extends BlockSchema> {
40
41
  onKeyDown: (_event: KeyboardEvent) => void;
41
42
  onMouseDown: (event: MouseEvent) => void;
42
43
  onMouseMove: (event: MouseEvent) => void;
43
- onScroll: () => void;
44
44
  destroy(): void;
45
45
  addBlock(): void;
46
46
  getStaticParams(): BlockSideMenuStaticParams<BSchema>;
@@ -3,9 +3,8 @@ import { BlockNoteEditor } from "../../BlockNoteEditor";
3
3
  import { BlockSchema } from "../Blocks/api/blockTypes";
4
4
  export type FormattingToolbarStaticParams<BSchema extends BlockSchema> = {
5
5
  editor: BlockNoteEditor<BSchema>;
6
+ getReferenceRect: () => DOMRect;
6
7
  };
7
- export type FormattingToolbarDynamicParams = {
8
- referenceRect: DOMRect;
9
- };
8
+ export type FormattingToolbarDynamicParams = {};
10
9
  export type FormattingToolbar = EditorElement<FormattingToolbarDynamicParams>;
11
10
  export type FormattingToolbarFactory<BSchema extends BlockSchema> = ElementFactory<FormattingToolbarStaticParams<BSchema>, FormattingToolbarDynamicParams>;
@@ -2,7 +2,7 @@ import { Editor } from "@tiptap/core";
2
2
  import { EditorState, Plugin, PluginKey } from "prosemirror-state";
3
3
  import { EditorView } from "prosemirror-view";
4
4
  import { BlockNoteEditor, BlockSchema } from "../..";
5
- import { FormattingToolbar, FormattingToolbarDynamicParams, FormattingToolbarFactory, FormattingToolbarStaticParams } from "./FormattingToolbarFactoryTypes";
5
+ import { FormattingToolbar, FormattingToolbarFactory, FormattingToolbarStaticParams } from "./FormattingToolbarFactoryTypes";
6
6
  export interface FormattingToolbarPluginProps<BSchema extends BlockSchema> {
7
7
  pluginKey: PluginKey;
8
8
  tiptapEditor: Editor;
@@ -21,6 +21,7 @@ export declare class FormattingToolbarView<BSchema extends BlockSchema> {
21
21
  preventShow: boolean;
22
22
  toolbarIsOpen: boolean;
23
23
  prevWasEditable: boolean | null;
24
+ private lastPosition;
24
25
  shouldShow: (props: {
25
26
  view: EditorView;
26
27
  state: EditorState;
@@ -35,11 +36,9 @@ export declare class FormattingToolbarView<BSchema extends BlockSchema> {
35
36
  blurHandler: ({ event }: {
36
37
  event: FocusEvent;
37
38
  }) => void;
38
- scrollHandler: () => void;
39
39
  update(view: EditorView, oldState?: EditorState): void;
40
40
  destroy(): void;
41
41
  getSelectionBoundingBox(): DOMRect;
42
42
  getStaticParams(): FormattingToolbarStaticParams<BSchema>;
43
- getDynamicParams(): FormattingToolbarDynamicParams;
44
43
  }
45
44
  export declare const createFormattingToolbarPlugin: <BSchema extends Record<string, import("../..").BlockSpec<string, import("../..").PropSchema>>>(options: FormattingToolbarPluginProps<BSchema>) => Plugin<any>;
@@ -2,11 +2,11 @@ import { EditorElement, ElementFactory } from "../../shared/EditorElement";
2
2
  export type HyperlinkToolbarStaticParams = {
3
3
  editHyperlink: (url: string, text: string) => void;
4
4
  deleteHyperlink: () => void;
5
+ getReferenceRect: () => DOMRect;
5
6
  };
6
7
  export type HyperlinkToolbarDynamicParams = {
7
8
  url: string;
8
9
  text: string;
9
- referenceRect: DOMRect;
10
10
  };
11
11
  export type HyperlinkToolbar = EditorElement<HyperlinkToolbarDynamicParams>;
12
12
  export type HyperlinkToolbarFactory = ElementFactory<HyperlinkToolbarStaticParams, HyperlinkToolbarDynamicParams>;
@@ -0,0 +1,2 @@
1
+ import i18next from "i18next";
2
+ export default i18next;
@@ -0,0 +1,51 @@
1
+ export declare const translation: {
2
+ en: {
3
+ translation: {
4
+ placeholder: string;
5
+ heading: string;
6
+ list: string;
7
+ };
8
+ };
9
+ de: {
10
+ translation: {
11
+ placeholder: string;
12
+ heading: string;
13
+ list: string;
14
+ };
15
+ };
16
+ it: {
17
+ translation: {
18
+ placeholder: string;
19
+ heading: string;
20
+ list: string;
21
+ };
22
+ };
23
+ es: {
24
+ translation: {
25
+ placeholder: string;
26
+ heading: string;
27
+ list: string;
28
+ };
29
+ };
30
+ fr: {
31
+ translation: {
32
+ placeholder: string;
33
+ heading: string;
34
+ list: string;
35
+ };
36
+ };
37
+ fi: {
38
+ translation: {
39
+ placeholder: string;
40
+ heading: string;
41
+ list: string;
42
+ };
43
+ };
44
+ sv: {
45
+ translation: {
46
+ placeholder: string;
47
+ heading: string;
48
+ list: string;
49
+ };
50
+ };
51
+ };
@@ -1,7 +1,7 @@
1
- export type RequiredStaticParams = Record<string, any>;
2
- export type RequiredDynamicParams = Record<string, any> & {
3
- referenceRect: DOMRect;
1
+ export type RequiredStaticParams = Record<string, any> & {
2
+ getReferenceRect: () => DOMRect;
4
3
  };
4
+ export type RequiredDynamicParams = Record<string, any> & {};
5
5
  export type EditorElement<ElementDynamicParams extends RequiredDynamicParams> = {
6
6
  element: HTMLElement | undefined;
7
7
  render: (params: ElementDynamicParams, isHidden: boolean) => void;
@@ -2,11 +2,11 @@ import { EditorElement, ElementFactory } from "../../EditorElement";
2
2
  import { SuggestionItem } from "./SuggestionItem";
3
3
  export type SuggestionsMenuStaticParams<T extends SuggestionItem> = {
4
4
  itemCallback: (item: T) => void;
5
+ getReferenceRect: () => DOMRect;
5
6
  };
6
7
  export type SuggestionsMenuDynamicParams<T extends SuggestionItem> = {
7
8
  items: T[];
8
9
  keyboardHoveredItemIndex: number;
9
- referenceRect: DOMRect;
10
10
  };
11
11
  export type SuggestionsMenu<T extends SuggestionItem> = EditorElement<SuggestionsMenuDynamicParams<T>>;
12
12
  export type SuggestionsMenuFactory<T extends SuggestionItem> = ElementFactory<SuggestionsMenuStaticParams<T>, SuggestionsMenuDynamicParams<T>>;
@@ -1,13 +0,0 @@
1
- export declare const Alert: import("./blockTypes").BlockSpec<"alert", {
2
- readonly textAlignment: {
3
- default: "left";
4
- values: readonly ["left", "center", "right", "justify"];
5
- };
6
- readonly textColor: {
7
- default: "black";
8
- };
9
- readonly type: {
10
- readonly default: "warning";
11
- readonly values: readonly ["warning", "error", "info", "success"];
12
- };
13
- }>;
@@ -1,13 +0,0 @@
1
- export declare const Alert2: import("./blockTypes").BlockSpec<"alert2", {
2
- readonly textAlignment: {
3
- default: "left";
4
- values: readonly ["left", "center", "right", "justify"];
5
- };
6
- readonly textColor: {
7
- default: "black";
8
- };
9
- readonly type: {
10
- readonly default: "warning";
11
- readonly values: readonly ["warning", "error", "info", "success"];
12
- };
13
- }>;