@blocknote/mantine 0.13.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 (54) hide show
  1. package/LICENSE +373 -0
  2. package/dist/blocknote-mantine.js +1532 -0
  3. package/dist/blocknote-mantine.js.map +1 -0
  4. package/dist/blocknote-mantine.umd.cjs +28 -0
  5. package/dist/blocknote-mantine.umd.cjs.map +1 -0
  6. package/dist/style.css +1 -0
  7. package/dist/webpack-stats.json +1 -0
  8. package/package.json +88 -0
  9. package/src/BlockNoteTheme.ts +153 -0
  10. package/src/defaultThemes.ts +159 -0
  11. package/src/form/TextInput.tsx +44 -0
  12. package/src/index.tsx +172 -0
  13. package/src/mantineStyles.css +138 -0
  14. package/src/menu/Menu.tsx +252 -0
  15. package/src/panel/Panel.tsx +50 -0
  16. package/src/panel/PanelButton.tsx +26 -0
  17. package/src/panel/PanelFileInput.tsx +26 -0
  18. package/src/panel/PanelTab.tsx +18 -0
  19. package/src/panel/PanelTextInput.tsx +27 -0
  20. package/src/popover/Popover.tsx +53 -0
  21. package/src/sideMenu/SideMenu.tsx +20 -0
  22. package/src/sideMenu/SideMenuButton.tsx +57 -0
  23. package/src/style.css +490 -0
  24. package/src/suggestionMenu/SuggestionMenu.tsx +25 -0
  25. package/src/suggestionMenu/SuggestionMenuEmptyItem.tsx +22 -0
  26. package/src/suggestionMenu/SuggestionMenuItem.tsx +47 -0
  27. package/src/suggestionMenu/SuggestionMenuLabel.tsx +20 -0
  28. package/src/suggestionMenu/SuggestionMenuLoader.tsx +20 -0
  29. package/src/tableHandle/TableHandle.tsx +37 -0
  30. package/src/toolbar/Toolbar.tsx +36 -0
  31. package/src/toolbar/ToolbarButton.tsx +106 -0
  32. package/src/toolbar/ToolbarSelect.tsx +69 -0
  33. package/types/src/BlockNoteTheme.d.ts +33 -0
  34. package/types/src/defaultThemes.d.ts +143 -0
  35. package/types/src/form/TextInput.d.ts +13 -0
  36. package/types/src/index.d.ts +14 -0
  37. package/types/src/menu/Menu.d.ts +24 -0
  38. package/types/src/panel/Panel.d.ts +12 -0
  39. package/types/src/panel/PanelButton.d.ts +11 -0
  40. package/types/src/panel/PanelFileInput.d.ts +7 -0
  41. package/types/src/panel/PanelTab.d.ts +5 -0
  42. package/types/src/panel/PanelTextInput.d.ts +8 -0
  43. package/types/src/popover/Popover.d.ts +9 -0
  44. package/types/src/sideMenu/SideMenu.d.ts +5 -0
  45. package/types/src/sideMenu/SideMenuButton.d.ts +15 -0
  46. package/types/src/suggestionMenu/SuggestionMenu.d.ts +6 -0
  47. package/types/src/suggestionMenu/SuggestionMenuEmptyItem.d.ts +5 -0
  48. package/types/src/suggestionMenu/SuggestionMenuItem.d.ts +8 -0
  49. package/types/src/suggestionMenu/SuggestionMenuLabel.d.ts +5 -0
  50. package/types/src/suggestionMenu/SuggestionMenuLoader.d.ts +5 -0
  51. package/types/src/tableHandle/TableHandle.d.ts +14 -0
  52. package/types/src/toolbar/Toolbar.d.ts +10 -0
  53. package/types/src/toolbar/ToolbarButton.d.ts +12 -0
  54. package/types/src/toolbar/ToolbarSelect.d.ts +12 -0
package/src/style.css ADDED
@@ -0,0 +1,490 @@
1
+ @import url("@blocknote/react/style.css");
2
+ @import url("./mantineStyles.css");
3
+
4
+ /* Mantine base styles*/
5
+
6
+ /* Mantine Badge component base styles */
7
+ .bn-container .mantine-Badge-root {
8
+ background-color: var(--bn-colors-tooltip-background);
9
+ color: var(--bn-colors-tooltip-text);
10
+ }
11
+
12
+ /* Mantine FileInput component base styles */
13
+ .bn-container .mantine-FileInput-input {
14
+ align-items: center;
15
+ background-color: var(--bn-colors-menu-background);
16
+ border: none;
17
+ border-radius: 4px;
18
+ color: var(--bn-colors-menu-text);
19
+ display: flex;
20
+ flex-direction: row;
21
+ justify-content: center;
22
+ }
23
+
24
+ .bn-container .mantine-FileInput-input:hover {
25
+ background-color: var(--bn-colors-hovered-background);
26
+ }
27
+
28
+ .bn-container .mantine-FileInput-wrapper {
29
+ border: solid var(--bn-colors-border) 1px;
30
+ border-radius: 4px;
31
+ }
32
+
33
+ .bn-container .mantine-InputPlaceholder-placeholder {
34
+ color: var(--bn-colors-menu-text);
35
+ font-weight: 600;
36
+ }
37
+
38
+ /* Mantine Menu component base styles */
39
+ .bn-container .mantine-Menu-dropdown {
40
+ background-color: var(--bn-colors-menu-background);
41
+ border: var(--bn-border);
42
+ border-radius: var(--bn-border-radius-medium);
43
+ box-shadow: var(--bn-shadow-medium);
44
+ box-sizing: border-box;
45
+ color: var(--bn-colors-menu-text);
46
+ padding: 2px;
47
+ overflow: auto;
48
+ }
49
+
50
+ .bn-container .mantine-Menu-label {
51
+ background-color: var(--bn-colors-menu-background);
52
+ color: var(--bn-colors-menu-text);
53
+ }
54
+
55
+ .bn-container .mantine-Menu-item {
56
+ background-color: var(--bn-colors-menu-background);
57
+ border: none;
58
+ border-radius: var(--bn-border-radius-small);
59
+ color: var(--bn-colors-menu-text);
60
+ }
61
+
62
+ .bn-container .mantine-Menu-item[aria-selected="true"],
63
+ .bn-container .mantine-Menu-item:hover {
64
+ background-color: var(--bn-colors-hovered-background);
65
+ border: none;
66
+ color: var(--bn-colors-hovered-text);
67
+ }
68
+
69
+ /* Mantine Popover component base styles */
70
+ .bn-container .mantine-Popover-dropdown {
71
+ background-color: transparent;
72
+ border: none;
73
+ border-radius: 0;
74
+ box-shadow: none;
75
+ padding: 0;
76
+ }
77
+
78
+ /* Mantine Tabs component base styles */
79
+ .bn-container .mantine-Tabs-root {
80
+ width: 100%;
81
+ background-color: var(--bn-colors-menu-background);
82
+ }
83
+
84
+ .bn-container .mantine-Tabs-list:before {
85
+ border-color: var(--bn-colors-hovered-background);
86
+ }
87
+
88
+ .bn-container .mantine-Tabs-tab {
89
+ color: var(--bn-colors-menu-text);
90
+ border-color: var(--bn-colors-hovered-background);
91
+ }
92
+
93
+ .bn-container .mantine-Tabs-tab:hover {
94
+ background-color: var(--bn-colors-hovered-background);
95
+ border-color: var(--bn-colors-hovered-background);
96
+ color: var(--bn-colors-hovered-text);
97
+ }
98
+
99
+ .bn-container .mantine-Tabs-tab[data-active],
100
+ .bn-container .mantine-Tabs-tab[data-active]:hover {
101
+ border-color: var(--bn-colors-menu-text);
102
+ color: var(--bn-colors-menu-text);
103
+ }
104
+
105
+ .bn-container .mantine-Tabs-panel {
106
+ padding: 8px;
107
+ }
108
+
109
+ /* Mantine TextInput component base styles */
110
+ .bn-container .mantine-TextInput-input {
111
+ background-color: var(--bn-colors-menu-background);
112
+ border: solid var(--bn-colors-border) 1px;
113
+ border-radius: 4px;
114
+ color: var(--bn-colors-menu-text);
115
+ height: 32px;
116
+ }
117
+
118
+ /* Mantine Tooltip component base styles */
119
+ .bn-container .mantine-Tooltip-tooltip {
120
+ background-color: transparent;
121
+ border: none;
122
+ border-radius: 0;
123
+ box-shadow: none;
124
+ padding: 0;
125
+ }
126
+
127
+ /* UI element styling */
128
+
129
+ /* Select styling */
130
+ .bn-select {
131
+ overflow: auto;
132
+ }
133
+
134
+ /* Toolbar styling */
135
+ .bn-toolbar {
136
+ background-color: var(--bn-colors-menu-background);
137
+ border: var(--bn-border);
138
+ border-radius: var(--bn-border-radius-medium);
139
+ box-shadow: var(--bn-shadow-medium);
140
+ flex-wrap: nowrap;
141
+ gap: 2px;
142
+ padding: 2px;
143
+ width: fit-content;
144
+ }
145
+
146
+ .bn-toolbar:empty {
147
+ display: none;
148
+ }
149
+
150
+ .bn-toolbar .mantine-Button-root,
151
+ .bn-toolbar .mantine-ActionIcon-root {
152
+ background-color: var(--bn-colors-menu-background);
153
+ border: none;
154
+ border-radius: var(--bn-border-radius-small);
155
+ color: var(--bn-colors-menu-text);
156
+ }
157
+
158
+ .bn-toolbar .mantine-Button-root:hover,
159
+ .bn-toolbar .mantine-ActionIcon-root:hover {
160
+ background-color: var(--bn-colors-hovered-background);
161
+ border: none;
162
+ color: var(--bn-colors-hovered-text);
163
+ }
164
+
165
+ .bn-toolbar .mantine-Button-root[data-selected],
166
+ .bn-toolbar .mantine-ActionIcon-root[data-selected] {
167
+ background-color: var(--bn-colors-selected-background);
168
+ border: none;
169
+ color: var(--bn-colors-selected-text);
170
+ }
171
+
172
+ .bn-toolbar .mantine-Button-root[data-disabled],
173
+ .bn-toolbar .mantine-ActionIcon-root[data-disabled] {
174
+ background-color: var(--bn-colors-disabled-background);
175
+ border: none;
176
+ color: var(--bn-colors-disabled-text);
177
+ }
178
+
179
+ .bn-toolbar .mantine-Menu-item {
180
+ font-size: 12px;
181
+ height: 30px;
182
+ }
183
+
184
+ .bn-toolbar .mantine-Menu-item:hover {
185
+ background-color: var(--bn-colors-hovered-background);
186
+ }
187
+
188
+ .bn-container .bn-form-popover {
189
+ background-color: var(--bn-colors-menu-background);
190
+ border: var(--bn-border);
191
+ border-radius: var(--bn-border-radius-medium);
192
+ box-shadow: var(--bn-shadow-medium);
193
+ color: var(--bn-colors-menu-text);
194
+ gap: 4px;
195
+ min-width: 145px;
196
+ padding: 2px;
197
+ }
198
+
199
+ .bn-form-popover .mantine-TextInput-root,
200
+ .bn-form-popover .mantine-FileInput-root {
201
+ width: 300px;
202
+ }
203
+
204
+ .bn-form-popover .mantine-TextInput-wrapper,
205
+ .bn-form-popover .mantine-FileInput-wrapper {
206
+ padding: 0;
207
+ border-radius: 4px;
208
+ }
209
+
210
+ .bn-form-popover .mantine-TextInput-wrapper:hover {
211
+ background-color: var(--bn-colors-hovered-background);
212
+ }
213
+
214
+ .bn-form-popover .mantine-TextInput-input,
215
+ .bn-form-popover .mantine-FileInput-input {
216
+ border: none;
217
+ font-size: 12px;
218
+ }
219
+
220
+ .bn-form-popover .mantine-FileInput-input:hover {
221
+ background-color: var(--bn-colors-hovered-background);
222
+ }
223
+
224
+ .bn-form-popover .mantine-FileInput-section[data-position="left"] {
225
+ color: var(--bn-colors-menu-text);
226
+ }
227
+
228
+ .bn-form-popover .mantine-FileInput-placeholder {
229
+ color: var(--bn-colors-menu-text);
230
+ }
231
+
232
+ /* Suggestion Menu styling*/
233
+
234
+ /* Base styles for Suggestion Menus, copied from the Mantine Menu component. */
235
+ /* Unfortunately necessary, as we can't use a Menu.Dropdown component on its
236
+ own. */
237
+ /* https://github.com/mantinedev/mantine/blob/e3e3bb834de1f2f75a27dbc757dc0a2fc6a6cba8/packages/%40mantine/core/src/components/Menu/Menu.module.css */
238
+ .bn-suggestion-menu {
239
+ max-height: 100%;
240
+ position: relative;
241
+ box-shadow: var(--mantine-shadow-md);
242
+ border: calc(0.0625rem * var(--mantine-scale)) solid
243
+ var(--mantine-color-gray-2);
244
+ border-radius: var(--mantine-radius-default);
245
+ padding: 4px;
246
+ }
247
+
248
+ .bn-suggestion-menu-label {
249
+ color: var(--mantine-color-dimmed);
250
+ font-weight: 500;
251
+ font-size: var(--mantine-font-size-xs);
252
+ padding: calc(var(--mantine-spacing-xs) / 2) var(--mantine-spacing-sm);
253
+ cursor: default;
254
+ }
255
+
256
+ .bn-suggestion-menu-item {
257
+ font-size: var(--mantine-font-size-sm);
258
+ width: 100%;
259
+ padding: calc(var(--mantine-spacing-xs) / 1.5) var(--mantine-spacing-sm);
260
+ border-radius: var(--popover-radius, var(--mantine-radius-default));
261
+ color: var(--menu-item-color, var(--mantine-color-text));
262
+ display: flex;
263
+ align-items: center;
264
+ user-select: none;
265
+
266
+ &:where([data-disabled], :disabled) {
267
+ color: var(--mantine-color-dimmed);
268
+ opacity: 0.6;
269
+ pointer-events: none;
270
+ }
271
+ }
272
+
273
+ /* Additional Suggestion Menu styling*/
274
+ .bn-mt-suggestion-menu-item-body {
275
+ flex: 1;
276
+ }
277
+
278
+ .bn-mt-suggestion-menu-item-section {
279
+ display: flex;
280
+ justify-content: center;
281
+ align-items: center;
282
+
283
+ &:where([data-position="left"]) {
284
+ margin-inline-end: var(--mantine-spacing-xs);
285
+ }
286
+
287
+ &:where([data-position="right"]) {
288
+ margin-inline-start: var(--mantine-spacing-xs);
289
+ }
290
+ }
291
+
292
+ .bn-suggestion-menu {
293
+ background-color: var(--bn-colors-menu-background);
294
+ border: var(--bn-border);
295
+ border-radius: var(--bn-border-radius-medium);
296
+ box-shadow: var(--bn-shadow-medium);
297
+ box-sizing: border-box;
298
+ color: var(--bn-colors-menu-text);
299
+ overflow-y: auto;
300
+ padding: 2px;
301
+ }
302
+
303
+ .bn-suggestion-menu-item {
304
+ cursor: pointer;
305
+ height: 52px;
306
+ }
307
+
308
+ .bn-suggestion-menu-item[aria-selected="true"],
309
+ .bn-suggestion-menu-item:hover {
310
+ background-color: var(--bn-colors-hovered-background);
311
+ }
312
+
313
+ .bn-mt-suggestion-menu-item-section {
314
+ color: var(--bn-colors-tooltip-text);
315
+ }
316
+
317
+ .bn-mt-suggestion-menu-item-section[data-position="left"] {
318
+ background-color: var(--bn-colors-tooltip-background);
319
+ border-radius: var(--bn-border-radius-small);
320
+ padding: 8px;
321
+ }
322
+
323
+ .bn-mt-suggestion-menu-item-body {
324
+ align-items: stretch;
325
+ color: var(--bn-colors-menu-text);
326
+ display: flex;
327
+ flex: 1;
328
+ flex-direction: column;
329
+ justify-content: flex-start;
330
+ padding-right: 16px;
331
+ }
332
+
333
+ .bn-mt-suggestion-menu-item-title {
334
+ line-height: 20px;
335
+ font-weight: 500;
336
+ font-size: 14px;
337
+ margin: 0;
338
+ padding: 0;
339
+ }
340
+
341
+ .bn-mt-suggestion-menu-item-subtitle {
342
+ line-height: 16px;
343
+ font-size: 10px;
344
+ margin: 0;
345
+ padding: 0;
346
+ }
347
+
348
+ .bn-suggestion-menu-label {
349
+ color: var(--bn-colors-hovered-text);
350
+ }
351
+
352
+ .bn-suggestion-menu-loader {
353
+ height: 20px;
354
+ width: 100%;
355
+ }
356
+
357
+ .bn-suggestion-menu-loader span {
358
+ background-color: var(--bn-colors-side-menu);
359
+ }
360
+
361
+ /* Side Menu styling */
362
+ .bn-side-menu {
363
+ background-color: transparent;
364
+ overflow: visible;
365
+ }
366
+
367
+ .bn-side-menu .mantine-Menu-item,
368
+ .bn-table-handle-menu .mantine-Menu-item {
369
+ font-size: 12px;
370
+ height: 30px;
371
+ }
372
+
373
+ .bn-side-menu .mantine-UnstyledButton-root:not(.mantine-Menu-item) {
374
+ background-color: transparent;
375
+ }
376
+
377
+ .bn-side-menu .mantine-UnstyledButton-root:hover {
378
+ background-color: var(--bn-colors-hovered-background);
379
+ }
380
+
381
+ .bn-side-menu .mantine-UnstyledButton-root:not(.mantine-Menu-item) svg {
382
+ background-color: transparent;
383
+ color: var(--bn-colors-side-menu);
384
+ height: 22px;
385
+ width: 22px;
386
+ }
387
+
388
+ .bn-side-menu > [draggable="true"] {
389
+ display: flex;
390
+ }
391
+
392
+ .bn-side-menu .mantine-Menu-dropdown {
393
+ min-width: 100px;
394
+ padding: 2px;
395
+ position: absolute;
396
+ }
397
+
398
+ /* Image Panel styling*/
399
+ .bn-panel {
400
+ background-color: var(--bn-colors-menu-background);
401
+ border: var(--bn-border);
402
+ border-radius: var(--bn-border-radius-medium);
403
+ box-shadow: var(--bn-shadow-medium);
404
+ padding: 2px;
405
+ width: 500px;
406
+ }
407
+
408
+ .bn-panel .bn-tab-panel {
409
+ align-items: center;
410
+ display: flex;
411
+ flex-direction: column;
412
+ gap: 8px;
413
+ width: 100%;
414
+ }
415
+
416
+ .bn-panel .mantine-TextInput-root,
417
+ .bn-panel .mantine-FileInput-root {
418
+ width: 100%;
419
+ }
420
+
421
+ .bn-panel .mantine-Button-root {
422
+ background-color: var(--bn-colors-menu-background);
423
+ border: solid var(--bn-colors-border) 1px;
424
+ border-radius: var(--bn-border-radius-small);
425
+ color: var(--bn-colors-menu-text);
426
+ height: 32px;
427
+ width: 60%;
428
+ }
429
+
430
+ .bn-panel .mantine-Button-root:hover {
431
+ background-color: var(--bn-colors-hovered-background);
432
+ }
433
+
434
+ .bn-panel.mantine-Text-root {
435
+ text-align: center;
436
+ }
437
+
438
+ /* Table Handle styling */
439
+ .bn-table-handle {
440
+ align-items: center;
441
+ background-color: var(--bn-colors-menu-background);
442
+ border: var(--bn-border);
443
+ border-radius: var(--bn-border-radius-small);
444
+ box-shadow: var(--bn-shadow-light);
445
+ color: var(--bn-colors-side-menu);
446
+ cursor: pointer;
447
+ display: flex;
448
+ justify-content: center;
449
+ overflow: visible;
450
+ padding: 0;
451
+ }
452
+
453
+ .bn-table-handle svg {
454
+ margin-inline: -4px;
455
+ }
456
+
457
+ .bn-table-handle:hover,
458
+ .bn-table-handle-dragging {
459
+ background-color: var(--bn-colors-hovered-background);
460
+ }
461
+
462
+ /* Drag Handle & Table Handle Menu styling */
463
+ .bn-container .bn-drag-handle-menu {
464
+ overflow: visible;
465
+ }
466
+
467
+ /* Tooltip styling */
468
+ .bn-tooltip {
469
+ background-color: var(--bn-colors-tooltip-background);
470
+ border: var(--bn-border);
471
+ border-radius: var(--bn-border-radius-medium);
472
+ box-shadow: var(--bn-shadow-medium);
473
+ color: var(--bn-colors-tooltip-text);
474
+ padding: 4px 10px;
475
+ text-align: center;
476
+ }
477
+
478
+ /* Additional menu styles */
479
+ .bn-tick-space {
480
+ padding: 0;
481
+ width: 20px;
482
+ }
483
+
484
+ .bn-mt-sub-menu-item
485
+ > .mantine-Menu-itemLabel
486
+ > div:not(.mantine-Menu-dropdown) {
487
+ align-items: center;
488
+ display: flex;
489
+ justify-content: space-between;
490
+ }
@@ -0,0 +1,25 @@
1
+ import * as Mantine from "@mantine/core";
2
+
3
+ import { assertEmpty } from "@blocknote/core";
4
+ import { ComponentProps } from "@blocknote/react";
5
+ import { forwardRef } from "react";
6
+
7
+ export const SuggestionMenu = forwardRef<
8
+ HTMLDivElement,
9
+ ComponentProps["SuggestionMenu"]["Root"]
10
+ >((props, ref) => {
11
+ const { className, children, id, ...rest } = props;
12
+
13
+ assertEmpty(rest);
14
+
15
+ return (
16
+ <Mantine.Stack
17
+ gap={0}
18
+ className={className}
19
+ ref={ref}
20
+ id={id}
21
+ role="listbox">
22
+ {children}
23
+ </Mantine.Stack>
24
+ );
25
+ });
@@ -0,0 +1,22 @@
1
+ import * as Mantine from "@mantine/core";
2
+
3
+ import { assertEmpty } from "@blocknote/core";
4
+ import { ComponentProps } from "@blocknote/react";
5
+ import { forwardRef } from "react";
6
+
7
+ export const SuggestionMenuEmptyItem = forwardRef<
8
+ HTMLDivElement,
9
+ ComponentProps["SuggestionMenu"]["EmptyItem"]
10
+ >((props, ref) => {
11
+ const { className, children, ...rest } = props;
12
+
13
+ assertEmpty(rest);
14
+
15
+ return (
16
+ <Mantine.Group className={className} ref={ref}>
17
+ <Mantine.Group className="bn-mt-suggestion-menu-item-label">
18
+ {children}
19
+ </Mantine.Group>
20
+ </Mantine.Group>
21
+ );
22
+ });
@@ -0,0 +1,47 @@
1
+ import * as Mantine from "@mantine/core";
2
+
3
+ import { assertEmpty } from "@blocknote/core";
4
+ import { ComponentProps } from "@blocknote/react";
5
+ import { forwardRef } from "react";
6
+
7
+ export const SuggestionMenuItem = forwardRef<
8
+ HTMLDivElement,
9
+ ComponentProps["SuggestionMenu"]["Item"]
10
+ >((props, ref) => {
11
+ const { className, isSelected, onClick, item, id, ...rest } = props;
12
+
13
+ assertEmpty(rest);
14
+
15
+ return (
16
+ <Mantine.Group
17
+ gap={0}
18
+ className={className}
19
+ ref={ref}
20
+ id={id}
21
+ role="option"
22
+ aria-selected={isSelected || undefined}>
23
+ {item.icon && (
24
+ <Mantine.Group
25
+ className="bn-mt-suggestion-menu-item-section"
26
+ data-position="left">
27
+ {item.icon}
28
+ </Mantine.Group>
29
+ )}
30
+ <Mantine.Stack gap={0} className="bn-mt-suggestion-menu-item-body">
31
+ <Mantine.Text className="bn-mt-suggestion-menu-item-title">
32
+ {item.title}
33
+ </Mantine.Text>
34
+ <Mantine.Text className="bn-mt-suggestion-menu-item-subtitle">
35
+ {item.subtext}
36
+ </Mantine.Text>
37
+ </Mantine.Stack>
38
+ {item.badge && (
39
+ <Mantine.Group
40
+ data-position="right"
41
+ className="bn-mt-suggestion-menu-item-section">
42
+ <Mantine.Badge size={"xs"}>{item.badge}</Mantine.Badge>
43
+ </Mantine.Group>
44
+ )}
45
+ </Mantine.Group>
46
+ );
47
+ });
@@ -0,0 +1,20 @@
1
+ import * as Mantine from "@mantine/core";
2
+
3
+ import { assertEmpty } from "@blocknote/core";
4
+ import { ComponentProps } from "@blocknote/react";
5
+ import { forwardRef } from "react";
6
+
7
+ export const SuggestionMenuLabel = forwardRef<
8
+ HTMLDivElement,
9
+ ComponentProps["SuggestionMenu"]["Label"]
10
+ >((props, ref) => {
11
+ const { className, children, ...rest } = props;
12
+
13
+ assertEmpty(rest);
14
+
15
+ return (
16
+ <Mantine.Group className={className} ref={ref}>
17
+ {children}
18
+ </Mantine.Group>
19
+ );
20
+ });
@@ -0,0 +1,20 @@
1
+ import * as Mantine from "@mantine/core";
2
+
3
+ import { assertEmpty } from "@blocknote/core";
4
+ import { ComponentProps } from "@blocknote/react";
5
+ import { forwardRef } from "react";
6
+
7
+ export const SuggestionMenuLoader = forwardRef<
8
+ HTMLDivElement,
9
+ ComponentProps["SuggestionMenu"]["Loader"]
10
+ >((props, ref) => {
11
+ const {
12
+ className,
13
+ children, // unused, using "dots" instead
14
+ ...rest
15
+ } = props;
16
+
17
+ assertEmpty(rest);
18
+
19
+ return <Mantine.Loader className={className} type="dots" ref={ref} />;
20
+ });
@@ -0,0 +1,37 @@
1
+ import { assertEmpty } from "@blocknote/core";
2
+ import { ComponentProps } from "@blocknote/react";
3
+ import { forwardRef } from "react";
4
+
5
+ export const TableHandle = forwardRef<
6
+ HTMLButtonElement,
7
+ ComponentProps["TableHandle"]["Root"]
8
+ >((props, ref) => {
9
+ const {
10
+ className,
11
+ children,
12
+ draggable,
13
+ onDragStart,
14
+ onDragEnd,
15
+ style,
16
+ label,
17
+ ...rest
18
+ } = props;
19
+
20
+ // false, because rest props can be added by mantine when button is used as a trigger
21
+ // assertEmpty in this case is only used at typescript level, not runtime level
22
+ assertEmpty(rest, false);
23
+
24
+ return (
25
+ <button
26
+ className={className}
27
+ ref={ref}
28
+ aria-label={label}
29
+ draggable={draggable}
30
+ onDragStart={onDragStart}
31
+ onDragEnd={onDragEnd}
32
+ style={style}
33
+ {...rest}>
34
+ {children}
35
+ </button>
36
+ );
37
+ });
@@ -0,0 +1,36 @@
1
+ import * as Mantine from "@mantine/core";
2
+
3
+ import { assertEmpty } from "@blocknote/core";
4
+ import { ComponentProps } from "@blocknote/react";
5
+ import { mergeRefs, useFocusTrap, useFocusWithin } from "@mantine/hooks";
6
+ import { forwardRef } from "react";
7
+
8
+ type ToolbarProps = ComponentProps["FormattingToolbar"]["Root"] &
9
+ ComponentProps["LinkToolbar"]["Root"];
10
+
11
+ export const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(
12
+ (props, ref) => {
13
+ const { className, children, onMouseEnter, onMouseLeave, ...rest } = props;
14
+
15
+ assertEmpty(rest);
16
+
17
+ // use a focus trap so that tab cycles through toolbar buttons, but only if focus is within the toolbar
18
+ const { ref: focusRef, focused } = useFocusWithin();
19
+
20
+ const trapRef = useFocusTrap(focused);
21
+
22
+ const combinedRef = mergeRefs(ref, focusRef, trapRef);
23
+
24
+ return (
25
+ <Mantine.Group
26
+ className={className}
27
+ ref={combinedRef}
28
+ role="toolbar"
29
+ // TODO: aria-label
30
+ onMouseEnter={onMouseEnter}
31
+ onMouseLeave={onMouseLeave}>
32
+ {children}
33
+ </Mantine.Group>
34
+ );
35
+ }
36
+ );