@blocknote/core 0.1.2 → 0.2.1-alpha.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.
Files changed (171) hide show
  1. package/README.md +12 -6
  2. package/dist/blocknote.js +1425 -5109
  3. package/dist/blocknote.js.map +1 -1
  4. package/dist/blocknote.umd.cjs +1 -53
  5. package/dist/blocknote.umd.cjs.map +1 -1
  6. package/dist/style.css +1 -1
  7. package/package.json +19 -32
  8. package/src/BlockNoteEditor.ts +54 -0
  9. package/src/BlockNoteExtensions.ts +52 -7
  10. package/src/assets/fonts-inter.css +92 -0
  11. package/src/editor.module.css +37 -0
  12. package/src/extensions/Blocks/BlockAttributes.ts +1 -3
  13. package/src/extensions/Blocks/PreviousBlockTypePlugin.ts +71 -18
  14. package/src/extensions/Blocks/helpers/getBlockInfoFromPos.ts +66 -0
  15. package/src/extensions/Blocks/index.ts +7 -3
  16. package/src/extensions/Blocks/nodes/Block.module.css +116 -74
  17. package/src/extensions/Blocks/nodes/Block.ts +413 -292
  18. package/src/extensions/Blocks/nodes/BlockGroup.ts +6 -6
  19. package/src/extensions/Blocks/nodes/BlockTypes/HeadingBlock/HeadingContent.ts +84 -0
  20. package/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/ListItemContent.ts +177 -0
  21. package/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/OrderedListItemIndexPlugin.ts +77 -0
  22. package/src/extensions/Blocks/nodes/BlockTypes/TextBlock/TextContent.ts +34 -0
  23. package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +20 -0
  24. package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +27 -9
  25. package/src/extensions/DraggableBlocks/{DraggableBlocksPlugin.tsx → DraggableBlocksPlugin.ts} +227 -147
  26. package/src/extensions/FormattingToolbar/FormattingToolbarExtension.ts +29 -0
  27. package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +35 -0
  28. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +308 -0
  29. package/src/extensions/HyperlinkToolbar/HyperlinkMark.ts +28 -0
  30. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.ts +19 -0
  31. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +251 -0
  32. package/src/extensions/Placeholder/PlaceholderExtension.ts +5 -2
  33. package/src/extensions/SlashMenu/SlashMenuExtension.ts +9 -1
  34. package/src/extensions/SlashMenu/SlashMenuItem.ts +1 -3
  35. package/src/extensions/SlashMenu/defaultCommands.tsx +33 -22
  36. package/src/extensions/TrailingNode/TrailingNodeExtension.ts +4 -4
  37. package/src/extensions/UniqueID/UniqueID.ts +14 -1
  38. package/src/index.ts +8 -4
  39. package/src/shared/EditorElement.ts +10 -0
  40. package/src/shared/plugins/suggestion/SuggestionItem.ts +1 -8
  41. package/src/shared/plugins/suggestion/SuggestionPlugin.ts +222 -101
  42. package/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts +21 -0
  43. package/src/{utils.ts → shared/utils.ts} +0 -0
  44. package/types/src/BlockNoteEditor.d.ts +13 -0
  45. package/types/src/BlockNoteExtensions.d.ts +12 -1
  46. package/types/src/EditorElement.d.ts +7 -0
  47. package/types/src/extensions/Blocks/PreviousBlockTypePlugin.d.ts +1 -1
  48. package/types/src/extensions/Blocks/helpers/getBlockInfoFromPos.d.ts +19 -0
  49. package/types/src/extensions/Blocks/nodes/Block.d.ts +11 -19
  50. package/types/src/extensions/Blocks/nodes/BlockTypes/HeadingBlock/HeadingContent.d.ts +8 -0
  51. package/types/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/ListItemContent.d.ts +8 -0
  52. package/types/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/OrderedListItemIndexPlugin.d.ts +2 -0
  53. package/types/src/extensions/Blocks/nodes/BlockTypes/TextBlock/TextContent.d.ts +6 -0
  54. package/types/src/extensions/BubbleMenu/BubbleMenuExtension.d.ts +4 -1
  55. package/types/src/extensions/BubbleMenu/BubbleMenuFactoryTypes.d.ts +27 -0
  56. package/types/src/extensions/BubbleMenu/BubbleMenuPlugin.d.ts +10 -12
  57. package/types/src/extensions/DraggableBlocks/BlockMenuFactoryTypes.d.ts +12 -0
  58. package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +14 -0
  59. package/types/src/extensions/DraggableBlocks/DragMenuFactoryTypes.d.ts +18 -0
  60. package/types/src/extensions/DraggableBlocks/DraggableBlocksExtension.d.ts +9 -3
  61. package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +23 -1
  62. package/types/src/extensions/FormattingToolbar/FormattingToolbarExtension.d.ts +8 -0
  63. package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +23 -0
  64. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +43 -0
  65. package/types/src/extensions/HyperlinkToolbar/HyperlinkMark.d.ts +8 -0
  66. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.d.ts +12 -0
  67. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +11 -0
  68. package/types/src/extensions/Hyperlinks/HyperlinkMark.d.ts +2 -1
  69. package/types/src/extensions/Hyperlinks/HyperlinkMenuFactoryTypes.d.ts +11 -0
  70. package/types/src/extensions/Hyperlinks/HyperlinkMenuPlugin.d.ts +10 -1
  71. package/types/src/extensions/SlashMenu/SlashMenuExtension.d.ts +3 -1
  72. package/types/src/extensions/SlashMenu/SlashMenuItem.d.ts +2 -4
  73. package/types/src/index.d.ts +8 -3
  74. package/types/src/shared/EditorElement.d.ts +6 -0
  75. package/types/src/shared/plugins/suggestion/SuggestionItem.d.ts +1 -6
  76. package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +15 -10
  77. package/types/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.d.ts +12 -0
  78. package/types/src/shared/utils.d.ts +2 -0
  79. package/types/src/utils.d.ts +2 -2
  80. package/src/BlockNoteTheme.ts +0 -150
  81. package/src/EditorContent.tsx +0 -2
  82. package/src/extensions/Blocks/OrderedListPlugin.ts +0 -46
  83. package/src/extensions/Blocks/commands/joinBackward.ts +0 -274
  84. package/src/extensions/Blocks/helpers/setBlockHeading.ts +0 -30
  85. package/src/extensions/Blocks/nodes/Content.ts +0 -63
  86. package/src/extensions/Blocks/rule.ts +0 -48
  87. package/src/extensions/BubbleMenu/BubbleMenuExtension.tsx +0 -36
  88. package/src/extensions/BubbleMenu/BubbleMenuPlugin.ts +0 -245
  89. package/src/extensions/BubbleMenu/component/BubbleMenu.tsx +0 -240
  90. package/src/extensions/BubbleMenu/component/LinkToolbarButton.tsx +0 -67
  91. package/src/extensions/DraggableBlocks/components/DragHandle.tsx +0 -102
  92. package/src/extensions/DraggableBlocks/components/DragHandleMenu.tsx +0 -19
  93. package/src/extensions/Hyperlinks/HyperlinkMark.tsx +0 -16
  94. package/src/extensions/Hyperlinks/HyperlinkMenuPlugin.tsx +0 -165
  95. package/src/extensions/Hyperlinks/menus/EditHyperlinkMenu.tsx +0 -44
  96. package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItem.tsx +0 -34
  97. package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemIcon.tsx +0 -31
  98. package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemInput.tsx +0 -40
  99. package/src/extensions/Hyperlinks/menus/HoverHyperlinkMenu.tsx +0 -37
  100. package/src/extensions/Hyperlinks/menus/HyperlinkMenu.tsx +0 -63
  101. package/src/fonts-inter.css +0 -94
  102. package/src/globals.css +0 -28
  103. package/src/root.module.css +0 -19
  104. package/src/shared/components/toolbar/Toolbar.tsx +0 -10
  105. package/src/shared/components/toolbar/ToolbarButton.tsx +0 -57
  106. package/src/shared/components/toolbar/ToolbarDropdown.tsx +0 -35
  107. package/src/shared/components/toolbar/ToolbarDropdownItem.tsx +0 -35
  108. package/src/shared/components/toolbar/ToolbarDropdownTarget.tsx +0 -31
  109. package/src/shared/components/tooltip/TooltipContent.module.css +0 -15
  110. package/src/shared/components/tooltip/TooltipContent.tsx +0 -23
  111. package/src/shared/hooks/useEditorForceUpdate.tsx +0 -30
  112. package/src/shared/plugins/suggestion/SuggestionListReactRenderer.tsx +0 -236
  113. package/src/shared/plugins/suggestion/components/SuggestionGroup.tsx +0 -47
  114. package/src/shared/plugins/suggestion/components/SuggestionGroupItem.tsx +0 -82
  115. package/src/shared/plugins/suggestion/components/SuggestionList.tsx +0 -92
  116. package/src/useEditor.ts +0 -51
  117. package/types/src/BlockNoteTheme.d.ts +0 -2
  118. package/types/src/EditorContent.d.ts +0 -1
  119. package/types/src/commands/indentation.d.ts +0 -2
  120. package/types/src/extensions/Blocks/OrderedListPlugin.d.ts +0 -2
  121. package/types/src/extensions/Blocks/commands/joinBackward.d.ts +0 -14
  122. package/types/src/extensions/Blocks/helpers/setBlockHeading.d.ts +0 -5
  123. package/types/src/extensions/Blocks/nodes/Content.d.ts +0 -5
  124. package/types/src/extensions/Blocks/rule.d.ts +0 -16
  125. package/types/src/extensions/BubbleMenu/component/BubbleMenu.d.ts +0 -5
  126. package/types/src/extensions/BubbleMenu/component/DropdownBlockItem.d.ts +0 -10
  127. package/types/src/extensions/BubbleMenu/component/LinkToolbarButton.d.ts +0 -11
  128. package/types/src/extensions/DraggableBlocks/components/DragHandle.d.ts +0 -12
  129. package/types/src/extensions/DraggableBlocks/components/DragHandleMenu.d.ts +0 -6
  130. package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenu.d.ts +0 -11
  131. package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItem.d.ts +0 -13
  132. package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemIcon.d.ts +0 -8
  133. package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemInput.d.ts +0 -9
  134. package/types/src/extensions/Hyperlinks/menus/HoverHyperlinkMenu.d.ts +0 -12
  135. package/types/src/extensions/Hyperlinks/menus/HyperlinkBasicMenu.d.ts +0 -12
  136. package/types/src/extensions/Hyperlinks/menus/HyperlinkEditMenu.d.ts +0 -10
  137. package/types/src/extensions/Hyperlinks/menus/HyperlinkMenu.d.ts +0 -21
  138. package/types/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInput.d.ts +0 -39
  139. package/types/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInputStyles.d.ts +0 -1
  140. package/types/src/extensions/Hyperlinks/menus/atlaskit/ToolbarComponent.d.ts +0 -11
  141. package/types/src/extensions/Hyperlinks/menus/helpers/PanelTextInput.d.ts +0 -39
  142. package/types/src/extensions/Hyperlinks/menus/helpers/PanelTextInputStyles.d.ts +0 -3
  143. package/types/src/extensions/Hyperlinks/menus/helpers/ToolbarComponent.d.ts +0 -13
  144. package/types/src/extensions/helpers/formatKeyboardShortcut.d.ts +0 -1
  145. package/types/src/lib/atlaskit/browser.d.ts +0 -12
  146. package/types/src/nodes/ChildgroupNode.d.ts +0 -28
  147. package/types/src/nodes/patchNodes.d.ts +0 -1
  148. package/types/src/plugins/TreeViewPlugin/index.d.ts +0 -2
  149. package/types/src/plugins/animation.d.ts +0 -2
  150. package/types/src/react/BlockNoteComposer.d.ts +0 -17
  151. package/types/src/react/BlockNotePlugin.d.ts +0 -1
  152. package/types/src/react/index.d.ts +0 -3
  153. package/types/src/react/useBlockNoteSetup.d.ts +0 -2
  154. package/types/src/registerBlockNote.d.ts +0 -2
  155. package/types/src/shared/components/toolbar/SimpleToolbarButton.d.ts +0 -15
  156. package/types/src/shared/components/toolbar/SimpleToolbarDropdown.d.ts +0 -11
  157. package/types/src/shared/components/toolbar/SimpleToolbarDropdownItem.d.ts +0 -11
  158. package/types/src/shared/components/toolbar/Toolbar.d.ts +0 -4
  159. package/types/src/shared/components/toolbar/ToolbarButton.d.ts +0 -15
  160. package/types/src/shared/components/toolbar/ToolbarDropdown.d.ts +0 -17
  161. package/types/src/shared/components/toolbar/ToolbarDropdownItem.d.ts +0 -11
  162. package/types/src/shared/components/toolbar/ToolbarDropdownTarget.d.ts +0 -8
  163. package/types/src/shared/components/toolbar/ToolbarSeparator.d.ts +0 -2
  164. package/types/src/shared/components/tooltip/TooltipContent.d.ts +0 -15
  165. package/types/src/shared/hooks/useEditorForceUpdate.d.ts +0 -2
  166. package/types/src/shared/plugins/suggestion/SuggestionListReactRenderer.d.ts +0 -71
  167. package/types/src/shared/plugins/suggestion/components/SuggestionGroup.d.ts +0 -23
  168. package/types/src/shared/plugins/suggestion/components/SuggestionGroupItem.d.ts +0 -9
  169. package/types/src/shared/plugins/suggestion/components/SuggestionList.d.ts +0 -11
  170. package/types/src/themes/BlockNoteEditorTheme.d.ts +0 -11
  171. package/types/src/useEditor.d.ts +0 -11
@@ -1,35 +0,0 @@
1
- import { Menu } from "@mantine/core";
2
- import { IconType } from "react-icons";
3
- import { TiTick } from "react-icons/ti";
4
- import { MouseEvent } from "react";
5
-
6
- export type ToolbarDropdownItemProps = {
7
- onClick?: (e: MouseEvent) => void;
8
- text: string;
9
- icon?: IconType;
10
- isSelected?: boolean;
11
- children?: any;
12
- isDisabled?: boolean;
13
- };
14
-
15
- export function ToolbarDropdownItem(props: ToolbarDropdownItemProps) {
16
- const ItemIcon = props.icon;
17
-
18
- return (
19
- <Menu.Item
20
- key={props.text}
21
- onClick={props.onClick}
22
- icon={ItemIcon && <ItemIcon size={16} />}
23
- rightSection={
24
- props.isSelected ? (
25
- <TiTick size={16} />
26
- ) : (
27
- // Ensures space for tick even if item isn't currently selected.
28
- <div style={{ width: "16px", padding: "0" }} />
29
- )
30
- }
31
- disabled={props.isDisabled}>
32
- {props.text}
33
- </Menu.Item>
34
- );
35
- }
@@ -1,31 +0,0 @@
1
- import { Button } from "@mantine/core";
2
- import { HiChevronDown } from "react-icons/hi";
3
- import { IconType } from "react-icons";
4
- import { forwardRef } from "react";
5
-
6
- export type ToolbarDropdownTargetProps = {
7
- text: string;
8
- icon?: IconType;
9
- isDisabled?: boolean;
10
- };
11
-
12
- export const ToolbarDropdownTarget = forwardRef<
13
- HTMLButtonElement,
14
- ToolbarDropdownTargetProps
15
- >((props: ToolbarDropdownTargetProps, ref) => {
16
- const { text, icon, isDisabled, ...others } = props;
17
-
18
- const TargetIcon = props.icon;
19
- return (
20
- <Button
21
- leftIcon={TargetIcon && <TargetIcon size={16} />}
22
- rightIcon={<HiChevronDown />}
23
- size={"xs"}
24
- variant={"subtle"}
25
- disabled={props.isDisabled}
26
- ref={ref}
27
- {...others}>
28
- {props.text}
29
- </Button>
30
- );
31
- });
@@ -1,15 +0,0 @@
1
- .tooltip {
2
- color: var(--N40);
3
- background-color: var(--N800);
4
- box-shadow: 0 0 10px rgba(253, 254, 255, 0.8),
5
- 0 0 3px rgba(253, 254, 255, 0.4);
6
- border-radius: 2px;
7
- font-size: smaller;
8
- text-align: center;
9
- padding: 4px;
10
- }
11
-
12
- .secondaryText {
13
- font-weight: 400;
14
- opacity: 0.6;
15
- }
@@ -1,23 +0,0 @@
1
- import styles from "./TooltipContent.module.css";
2
-
3
- /**
4
- * Helper for the tooltip for inline bubble menu buttons.
5
- *
6
- * Often used to display a tooltip showing the command name + keyboard shortcut, e.g.:
7
- *
8
- * Bold
9
- * Ctrl+B
10
- *
11
- * TODO: maybe use default Tippy styles instead?
12
- */
13
- export const TooltipContent = (props: {
14
- mainTooltip: string;
15
- secondaryTooltip?: string;
16
- }) => (
17
- <div className={styles.tooltip}>
18
- <div>{props.mainTooltip}</div>
19
- {props.secondaryTooltip && (
20
- <div className={styles.secondaryText}>{props.secondaryTooltip}</div>
21
- )}
22
- </div>
23
- );
@@ -1,30 +0,0 @@
1
- import { Editor } from "@tiptap/core";
2
- import { useEffect, useState } from "react";
3
-
4
- function useForceUpdate() {
5
- const [, setValue] = useState(0);
6
-
7
- return () => setValue((value) => value + 1);
8
- }
9
-
10
- // This is a component that is similar to https://github.com/ueberdosis/tiptap/blob/main/packages/react/src/useEditor.ts
11
- // Use it to rerender a component whenever a transaction happens in the editor
12
- export const useEditorForceUpdate = (editor: Editor) => {
13
- const forceUpdate = useForceUpdate();
14
-
15
- useEffect(() => {
16
- const callback = () => {
17
- requestAnimationFrame(() => {
18
- requestAnimationFrame(() => {
19
- forceUpdate();
20
- });
21
- });
22
- };
23
-
24
- editor.on("transaction", callback);
25
- return () => {
26
- editor.off("transaction", callback);
27
- };
28
- // eslint-disable-next-line react-hooks/exhaustive-deps
29
- }, [editor]);
30
- };
@@ -1,236 +0,0 @@
1
- import { Editor as ReactEditor, ReactRenderer } from "@tiptap/react";
2
- import { Editor } from "@tiptap/core";
3
- import tippy, { Instance } from "tippy.js";
4
- import SuggestionItem from "./SuggestionItem";
5
- import {
6
- SuggestionList,
7
- SuggestionListProps,
8
- } from "./components/SuggestionList";
9
- import { BlockNoteTheme } from "../../../BlockNoteTheme";
10
- import { MantineProvider } from "@mantine/core";
11
-
12
- /**
13
- * The interface that each suggestion renderer should conform to.
14
- */
15
- export interface SuggestionRenderer<T extends SuggestionItem> {
16
- /**
17
- * Disposes of the suggestion menu.
18
- */
19
- onExit?: (props: SuggestionRendererProps<T>) => void;
20
-
21
- /**
22
- * Updates the suggestion menu.
23
- *
24
- * This function should be called when the renderer's `props` change,
25
- * after `onStart` has been called.
26
- */
27
- onUpdate?: (props: SuggestionRendererProps<T>) => void;
28
-
29
- /**
30
- * Creates and displays a new suggestion menu popup.
31
- */
32
- onStart?: (props: SuggestionRendererProps<T>) => void;
33
-
34
- /**
35
- * Function for handling key events
36
- */
37
- onKeyDown?: (event: KeyboardEvent) => boolean;
38
-
39
- /**
40
- * The DOM Element representing the suggestion menu
41
- */
42
- getComponent: () => Element | undefined;
43
- }
44
-
45
- export type SuggestionRendererProps<T extends SuggestionItem> = {
46
- /**
47
- * Object containing all suggestion items, grouped by their `groupName`.
48
- */
49
- groups: {
50
- [groupName: string]: T[];
51
- };
52
-
53
- /**
54
- * The total number of suggestion-items.
55
- */
56
- count: number;
57
-
58
- /**
59
- * This callback is executed whenever the user selects an item.
60
- *
61
- * @param item the selected item
62
- */
63
- onSelectItem: (item: T) => void;
64
-
65
- /**
66
- * A function returning the client rect to use as reference for positioning the suggestion menu popup.
67
- */
68
- clientRect: (() => DOMRect) | null;
69
-
70
- /**
71
- * This callback is executed when the suggestion menu needs to be closed,
72
- * e.g. when the user presses escape.
73
- */
74
- onClose: () => void;
75
- };
76
-
77
- /**
78
- * This function creates a SuggestionRenderer based on TipTap's ReactRenderer utility.
79
- *
80
- * The resulting renderer can be used to display a suggestion menu containing (grouped) suggestion items.
81
- *
82
- * This renderer also takes care of the following key events:
83
- * - Key up/down, for navigating the suggestion menu (selecting different items)
84
- * - Enter for picking the currently selected item and closing the menu
85
- * - Escape to close the menu, without taking action
86
- *
87
- * @param editor the TipTap editor
88
- * @returns the newly constructed SuggestionRenderer
89
- */
90
- export default function createRenderer<T extends SuggestionItem>(
91
- editor: Editor
92
- ): SuggestionRenderer<T> {
93
- let component: ReactRenderer;
94
- let popup: Instance[];
95
- let componentsDisposedOrDisposing = true;
96
- let selectedIndex = 0;
97
- let props: SuggestionRendererProps<T> | undefined;
98
-
99
- /**
100
- * Helper function to find out what item corresponds to a certain index.
101
- *
102
- * This function might throw an error if the index is invalid,
103
- * or when this function is not called in the proper environment.
104
- *
105
- * @param index the index
106
- * @returns the item that corresponds to the index
107
- */
108
- const itemByIndex = (index: number): T => {
109
- if (!props) {
110
- throw new Error("props not set");
111
- }
112
- let currentIndex = 0;
113
- for (const groupName in props.groups) {
114
- const items = props.groups[groupName];
115
- const groupSize = items.length;
116
- // Check if index lies within this group
117
- if (index < currentIndex + groupSize) {
118
- return items[index - currentIndex];
119
- }
120
- currentIndex += groupSize;
121
- }
122
- throw Error("item not found");
123
- };
124
-
125
- return {
126
- getComponent: () => {
127
- if (!popup || !popup[0]) {
128
- return undefined;
129
- }
130
- // return the tippy container element, this is used to ensure
131
- // that click events inside the menu are handled properly.
132
- return popup[0].reference;
133
- },
134
- onStart: (newProps) => {
135
- props = newProps;
136
- componentsDisposedOrDisposing = false;
137
- selectedIndex = 0;
138
- const componentProps: SuggestionListProps<T> = {
139
- groups: newProps.groups,
140
- count: newProps.count,
141
- onSelectItem: newProps.onSelectItem,
142
- selectedIndex,
143
- };
144
-
145
- component = new ReactRenderer(
146
- (props: SuggestionListProps<T>) => (
147
- <MantineProvider theme={BlockNoteTheme}>
148
- <SuggestionList {...props} />
149
- </MantineProvider>
150
- ),
151
- {
152
- editor: editor as ReactEditor,
153
- props: componentProps,
154
- }
155
- );
156
-
157
- popup = tippy("body", {
158
- getReferenceClientRect: newProps.clientRect,
159
- appendTo: () => document.body,
160
- content: component.element,
161
- showOnCreate: true,
162
- interactive: true,
163
- trigger: "manual",
164
- placement: "bottom-start",
165
- });
166
- },
167
-
168
- onUpdate: (newProps) => {
169
- props = newProps;
170
- if (props.groups !== component.props.groups) {
171
- // if the set of items is different (e.g.: by typing / searching), reset the selectedIndex to 0
172
- selectedIndex = 0;
173
- }
174
- const componentProps: SuggestionListProps<T> = {
175
- groups: props.groups,
176
- count: props.count,
177
- onSelectItem: props.onSelectItem,
178
- selectedIndex,
179
- };
180
- component.updateProps(componentProps);
181
-
182
- popup[0].setProps({
183
- getReferenceClientRect: props.clientRect,
184
- });
185
- },
186
-
187
- onKeyDown: (event) => {
188
- if (!props) {
189
- return false;
190
- }
191
- if (event.key === "ArrowUp") {
192
- selectedIndex = (selectedIndex + props.count - 1) % props.count;
193
- component.updateProps({
194
- selectedIndex,
195
- });
196
- return true;
197
- }
198
-
199
- if (event.key === "ArrowDown") {
200
- selectedIndex = (selectedIndex + 1) % props.count;
201
- component.updateProps({
202
- selectedIndex,
203
- });
204
- return true;
205
- }
206
-
207
- if (event.key === "Enter") {
208
- const item = itemByIndex(selectedIndex);
209
- props.onSelectItem(item);
210
- return true;
211
- }
212
-
213
- if (event.key === "Escape") {
214
- props.onClose();
215
- return true;
216
- }
217
- return false;
218
- },
219
-
220
- onExit: (_props) => {
221
- if (componentsDisposedOrDisposing) {
222
- return;
223
- }
224
- // onExit, first hide tippy popup so it shows fade-out
225
- // then (after 1 second, actually destroy resources)
226
- componentsDisposedOrDisposing = true;
227
- const popupToDestroy = popup[0];
228
- const componentToDestroy = component;
229
- popupToDestroy.hide();
230
- setTimeout(() => {
231
- popupToDestroy.destroy();
232
- componentToDestroy.destroy();
233
- }, 1000);
234
- },
235
- };
236
- }
@@ -1,47 +0,0 @@
1
- import { Menu } from "@mantine/core";
2
- import SuggestionItem from "../SuggestionItem";
3
- import { SuggestionGroupItem } from "./SuggestionGroupItem";
4
-
5
- type SuggestionGroupProps<T> = {
6
- /**
7
- * Name of the group
8
- */
9
- name: string;
10
-
11
- /**
12
- * The list of items
13
- */
14
- items: T[];
15
-
16
- /**
17
- * Index of the selected item in this group; relative to this item group (so 0 refers to the first item in this group)
18
- * This should be 'undefined' if none of the items in this group are selected
19
- */
20
- selectedIndex?: number;
21
-
22
- /**
23
- * Callback that gets executed when an item is clicked on.
24
- */
25
- clickItem: (item: T) => void;
26
- };
27
-
28
- export function SuggestionGroup<T extends SuggestionItem>(
29
- props: SuggestionGroupProps<T>
30
- ) {
31
- return (
32
- <>
33
- <Menu.Label>{props.name}</Menu.Label>
34
- {props.items.map((item, index) => {
35
- return (
36
- <SuggestionGroupItem
37
- item={item}
38
- key={index} // TODO: using index as key is not ideal for performance, better have ids on suggestionItems
39
- index={index}
40
- selectedIndex={props.selectedIndex}
41
- clickItem={props.clickItem}
42
- />
43
- );
44
- })}
45
- </>
46
- );
47
- }
@@ -1,82 +0,0 @@
1
- import SuggestionItem from "../SuggestionItem";
2
- import { useEffect, useRef } from "react";
3
- import { Badge, createStyles, Menu, Stack, Text } from "@mantine/core";
4
-
5
- const MIN_LEFT_MARGIN = 5;
6
-
7
- export type SuggestionGroupItemProps<T> = {
8
- item: T;
9
- index: number;
10
- selectedIndex?: number;
11
- clickItem: (item: T) => void;
12
- };
13
-
14
- export function SuggestionGroupItem<T extends SuggestionItem>(
15
- props: SuggestionGroupItemProps<T>
16
- ) {
17
- const itemRef = useRef<HTMLButtonElement>(null);
18
- const { classes } = createStyles({ root: {} })(undefined, {
19
- name: "SuggestionListItem",
20
- });
21
-
22
- function isSelected() {
23
- const isKeyboardSelected =
24
- props.selectedIndex !== undefined && props.selectedIndex === props.index;
25
- const isMouseSelected = itemRef.current?.matches(":hover");
26
-
27
- return isKeyboardSelected || isMouseSelected;
28
- }
29
-
30
- // Updates HTML "data-hovered" attribute which Mantine uses to set mouse hover styles.
31
- // Allows users to "hover" menu items when navigating using the keyboard.
32
- function updateSelection() {
33
- isSelected()
34
- ? itemRef.current?.setAttribute("data-hovered", "true")
35
- : itemRef.current?.removeAttribute("data-hovered");
36
- }
37
-
38
- useEffect(() => {
39
- // Updates whether the item is selected with the keyboard (triggered on selectedIndex prop change).
40
- updateSelection();
41
-
42
- if (
43
- isSelected() &&
44
- itemRef.current &&
45
- itemRef.current.getBoundingClientRect().left > MIN_LEFT_MARGIN //TODO: Kinda hacky, fix
46
- // This check is needed because initially the menu is initialized somewhere above outside the screen (with left = 1)
47
- // scrollIntoView() is called before the menu is set in the right place, and without the check would scroll to the top of the page every time
48
- ) {
49
- itemRef.current.scrollIntoView({
50
- behavior: "smooth",
51
- block: "nearest",
52
- });
53
- }
54
- });
55
-
56
- const Icon = props.item.icon;
57
-
58
- return (
59
- <Menu.Item
60
- className={classes.root}
61
- icon={Icon && <Icon size={18} />}
62
- onClick={() => props.clickItem(props.item)}
63
- // Ensures an item selected with both mouse & keyboard doesn't get deselected on mouse leave.
64
- onMouseLeave={() => {
65
- setTimeout(() => {
66
- updateSelection();
67
- });
68
- }}
69
- ref={itemRef}
70
- rightSection={
71
- props.item.shortcut && <Badge size={"xs"}>{props.item.shortcut}</Badge>
72
- }>
73
- <Stack>
74
- {/*Might need separate classes.*/}
75
- <Text size={14} weight={500}>
76
- {props.item.name}
77
- </Text>
78
- <Text size={10}>{props.item.hint}</Text>
79
- </Stack>
80
- </Menu.Item>
81
- );
82
- }
@@ -1,92 +0,0 @@
1
- import { createStyles, Menu } from "@mantine/core";
2
- import { SuggestionGroup } from "./SuggestionGroup";
3
- import SuggestionItem from "../SuggestionItem";
4
-
5
- export type SuggestionListProps<T> = {
6
- // Object containing all suggestion items, grouped by their `groupName`.
7
- groups: {
8
- [groupName: string]: T[];
9
- };
10
-
11
- //The total number of suggestion-items
12
- count: number;
13
-
14
- // This callback gets executed whenever an item is clicked on
15
- onSelectItem: (item: T) => void;
16
-
17
- // The index of the item that is currently selected (but not yet clicked on)
18
- selectedIndex: number;
19
- };
20
-
21
- // Stateless component that renders the suggestion list
22
- export function SuggestionList<T extends SuggestionItem>(
23
- props: SuggestionListProps<T>
24
- ) {
25
- const { classes } = createStyles({ root: {} })(undefined, {
26
- name: "SuggestionList",
27
- });
28
-
29
- const renderedGroups = [];
30
-
31
- let currentGroupIndex = 0;
32
-
33
- for (const groupName in props.groups) {
34
- const items = props.groups[groupName];
35
-
36
- renderedGroups.push(
37
- <SuggestionGroup
38
- key={groupName}
39
- name={groupName}
40
- items={items}
41
- selectedIndex={
42
- props.selectedIndex >= currentGroupIndex
43
- ? props.selectedIndex - currentGroupIndex
44
- : undefined
45
- }
46
- clickItem={props.onSelectItem}></SuggestionGroup>
47
- );
48
-
49
- currentGroupIndex += items.length;
50
- }
51
-
52
- return (
53
- <Menu
54
- /** Hacky fix to get the desired menu behaviour. The trigger="hover"
55
- * attribute allows focus to remain on the editor, allowing for suggestion
56
- * filtering. The closeDelay=10000000 attribute allows the menu to stay open
57
- * practically indefinitely, as normally hovering off it would cause it to
58
- * close due to trigger="hover".
59
- */
60
- defaultOpened={true}
61
- trigger={"hover"}
62
- closeDelay={10000000}>
63
- <Menu.Dropdown className={classes.root}>
64
- {renderedGroups.length > 0 ? (
65
- renderedGroups
66
- ) : (
67
- <Menu.Item>No match found</Menu.Item>
68
- )}
69
- </Menu.Dropdown>
70
- </Menu>
71
-
72
- // doesn't work well yet, maybe https://github.com/atomiks/tippyjs-react/issues/173
73
- // We now render the tippy element manually in SuggestionListReactRenderer
74
- // <Tippy
75
- // visible={true}
76
- // placement="bottom-start"
77
- // content={
78
- // <div className={styles.menuList}>
79
- // <PopupMenuGroup maxWidth="250px" maxHeight="400px">
80
- // {renderedGroups.length > 0 ? (
81
- // renderedGroups
82
- // ) : (
83
- // <Section title={"No match found"}> </Section>
84
- // )}
85
- // </PopupMenuGroup>
86
- // </div>
87
- // }
88
- // interactive={false}>
89
- // <div></div>
90
- // </Tippy>
91
- );
92
- }
package/src/useEditor.ts DELETED
@@ -1,51 +0,0 @@
1
- import { EditorOptions, useEditor as useEditorTiptap } from "@tiptap/react";
2
-
3
- import { DependencyList } from "react";
4
- import { getBlockNoteExtensions } from "./BlockNoteExtensions";
5
- import styles from "./editor.module.css";
6
- import rootStyles from "./root.module.css";
7
-
8
- type BlockNoteEditorOptions = EditorOptions & {
9
- enableBlockNoteExtensions: boolean;
10
- disableHistoryExtension: boolean;
11
- };
12
-
13
- const blockNoteExtensions = getBlockNoteExtensions();
14
-
15
- const blockNoteOptions = {
16
- enableInputRules: true,
17
- enablePasteRules: true,
18
- enableCoreExtensions: false,
19
- };
20
-
21
- /**
22
- * Main hook for importing a BlockNote editor into a react project
23
- */
24
- export const useEditor = (
25
- options: Partial<BlockNoteEditorOptions> = {},
26
- deps: DependencyList = []
27
- ) => {
28
- const extensions = options.disableHistoryExtension
29
- ? blockNoteExtensions.filter((e) => e.name !== "history")
30
- : blockNoteExtensions;
31
-
32
- const tiptapOptions = {
33
- ...blockNoteOptions,
34
- ...options,
35
- extensions:
36
- options.enableBlockNoteExtensions === false
37
- ? options.extensions
38
- : [...(options.extensions || []), ...extensions],
39
- editorProps: {
40
- attributes: {
41
- ...(options.editorProps?.attributes || {}),
42
- class: [
43
- styles.bnEditor,
44
- rootStyles.bnRoot,
45
- (options.editorProps?.attributes as any)?.class || "",
46
- ].join(" "),
47
- },
48
- },
49
- };
50
- return useEditorTiptap(tiptapOptions, deps);
51
- };
@@ -1,2 +0,0 @@
1
- import { MantineThemeOverride } from "@mantine/core";
2
- export declare const BlockNoteTheme: MantineThemeOverride;
@@ -1 +0,0 @@
1
- export { EditorContent } from "@tiptap/react";
@@ -1,2 +0,0 @@
1
- import { LexicalEditor } from "lexical";
2
- export declare function registerIndentationCommands(editor: LexicalEditor): () => void;
@@ -1,2 +0,0 @@
1
- import { Plugin } from "prosemirror-state";
2
- export declare const OrderedListPlugin: () => Plugin<any>;
@@ -1,14 +0,0 @@
1
- import { Command } from "prosemirror-state";
2
- /**
3
- * Code taken from https://github.com/ProseMirror/prosemirror-commands/blob/97a8cb5fac25e697d4693ce343e2e3b020a7fa2f/src/commands.ts
4
- * Reason for modification: https://github.com/YousefED/BlockNote/pull/11
5
- *
6
- * BlockA
7
- * BlockB
8
- * Order of behavior has been switched to make first and second blocks content
9
- * merge before trying to add second block as child of first
10
- *
11
- * behavior responsible for joining BlockB as A child of BlockA moved to (line 379 - 393 original file) after
12
- * behavior responsible for joining content of BlockA and BlockB (line 402 - 422 original file)
13
- */
14
- export declare const joinBackward: Command;
@@ -1,5 +0,0 @@
1
- import { Transaction } from "prosemirror-state";
2
- import { Level } from "../nodes/Block";
3
- declare type Dispatch = ((args?: any) => any) | undefined;
4
- export declare function setBlockHeading(tr: Transaction, dispatch: Dispatch, level?: Level): boolean;
5
- export {};
@@ -1,5 +0,0 @@
1
- import { Node } from "@tiptap/core";
2
- export interface IBlock {
3
- HTMLAttributes: Record<string, any>;
4
- }
5
- export declare const ContentBlock: Node<IBlock, any>;