@blocknote/core 0.9.4 → 0.9.5

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.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "homepage": "https://github.com/TypeCellOS/BlockNote",
4
4
  "private": false,
5
5
  "license": "MPL-2.0",
6
- "version": "0.9.4",
6
+ "version": "0.9.5",
7
7
  "files": [
8
8
  "dist",
9
9
  "types",
@@ -109,5 +109,5 @@
109
109
  "access": "public",
110
110
  "registry": "https://registry.npmjs.org/"
111
111
  },
112
- "gitHead": "31e3c53bdcc082e3793bbb5517462cc18abd9e22"
112
+ "gitHead": "d1720576466e2d32ebbfaff43a7a5e6f6333a600"
113
113
  }
@@ -38,7 +38,39 @@ export function propsToAttributes<
38
38
  // Props are displayed in kebab-case as HTML attributes. If a prop's
39
39
  // value is the same as its default, we don't display an HTML
40
40
  // attribute for it.
41
- parseHTML: (element) => element.getAttribute(camelToDataKebab(name)),
41
+ parseHTML: (element) => {
42
+ const value = element.getAttribute(camelToDataKebab(name));
43
+
44
+ if (value === null) {
45
+ return null;
46
+ }
47
+
48
+ if (typeof spec.default === "boolean") {
49
+ if (value === "true") {
50
+ return true;
51
+ }
52
+
53
+ if (value === "false") {
54
+ return false;
55
+ }
56
+
57
+ return null;
58
+ }
59
+
60
+ if (typeof spec.default === "number") {
61
+ const asNumber = parseFloat(value);
62
+ const isNumeric =
63
+ !Number.isNaN(asNumber) && Number.isFinite(asNumber);
64
+
65
+ if (isNumeric) {
66
+ return asNumber;
67
+ }
68
+
69
+ return null;
70
+ }
71
+
72
+ return value;
73
+ },
42
74
  renderHTML: (attributes) =>
43
75
  attributes[name] !== spec.default
44
76
  ? {
@@ -485,6 +485,51 @@ export const BlockContainer = Node.create<{
485
485
  }),
486
486
  ]);
487
487
 
488
+ const handleDelete = () =>
489
+ this.editor.commands.first(({ commands }) => [
490
+ // Deletes the selection if it's not empty.
491
+ () => commands.deleteSelection(),
492
+ // Merges block with the next one (at the same nesting level or lower),
493
+ // if one exists, the block has no children, and the selection is at the
494
+ // end of the block.
495
+ () =>
496
+ commands.command(({ state }) => {
497
+ const { node, contentNode, depth, endPos } = getBlockInfoFromPos(
498
+ state.doc,
499
+ state.selection.from
500
+ )!;
501
+
502
+ const blockAtDocEnd = false;
503
+ const selectionAtBlockEnd =
504
+ state.selection.$anchor.parentOffset ===
505
+ contentNode.firstChild!.nodeSize;
506
+ const selectionEmpty =
507
+ state.selection.anchor === state.selection.head;
508
+ const hasChildBlocks = node.childCount === 2;
509
+
510
+ if (
511
+ !blockAtDocEnd &&
512
+ selectionAtBlockEnd &&
513
+ selectionEmpty &&
514
+ !hasChildBlocks
515
+ ) {
516
+ let oldDepth = depth;
517
+ let newPos = endPos + 2;
518
+ let newDepth = state.doc.resolve(newPos).depth;
519
+
520
+ while (newDepth < oldDepth) {
521
+ oldDepth = newDepth;
522
+ newPos += 2;
523
+ newDepth = state.doc.resolve(newPos).depth;
524
+ }
525
+
526
+ return commands.BNMergeBlocks(newPos - 1);
527
+ }
528
+
529
+ return false;
530
+ }),
531
+ ]);
532
+
488
533
  const handleEnter = () =>
489
534
  this.editor.commands.first(({ commands }) => [
490
535
  // Removes a level of nesting if the block is empty & indented, while the selection is also empty & at the start
@@ -552,12 +597,14 @@ export const BlockContainer = Node.create<{
552
597
  state.selection.from
553
598
  )!;
554
599
 
600
+ const selectionAtBlockStart =
601
+ state.selection.$anchor.parentOffset === 0;
555
602
  const blockEmpty = node.textContent.length === 0;
556
603
 
557
604
  if (!blockEmpty) {
558
605
  chain()
559
606
  .deleteSelection()
560
- .BNSplitBlock(state.selection.from, false)
607
+ .BNSplitBlock(state.selection.from, selectionAtBlockStart)
561
608
  .run();
562
609
 
563
610
  return true;
@@ -569,6 +616,7 @@ export const BlockContainer = Node.create<{
569
616
 
570
617
  return {
571
618
  Backspace: handleBackspace,
619
+ Delete: handleDelete,
572
620
  Enter: handleEnter,
573
621
  // Always returning true for tab key presses ensures they're not captured by the browser. Otherwise, they blur the
574
622
  // editor since the browser will try to use tab for keyboard navigation.
@@ -346,6 +346,10 @@ export const setupSuggestionsMenu = <
346
346
 
347
347
  // Selects an item and closes the menu.
348
348
  if (event.key === "Enter") {
349
+ if (items.length === 0) {
350
+ return true;
351
+ }
352
+
349
353
  deactivate(view);
350
354
  editor._tiptapEditor
351
355
  .chain()
@@ -1,6 +0,0 @@
1
- import "@uppy/core/dist/style.css";
2
- import "@uppy/dashboard/dist/style.css";
3
- import "@uppy/drag-drop/dist/style.css";
4
- import "@uppy/file-input/dist/style.css";
5
- import "@uppy/progress-bar/dist/style.css";
6
- export declare const Image: BlockSpec<BType, PSchema, ContainsInlineContent>;
@@ -1 +0,0 @@
1
- export declare const uploadToTmpFilesOrg: (file: File) => Promise<any>;