@zm-editor/react 0.1.2 → 0.1.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/README.ko.md +260 -260
- package/README.md +300 -300
- package/dist/index.js +147 -84
- package/dist/styles.css +8078 -8078
- package/dist/variables.css +480 -480
- package/package.json +8 -8
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -9495,6 +9495,21 @@ function findNodePosFromDOM(editor, element) {
|
|
|
9495
9495
|
const pos = editor.view.posAtDOM(nodeElement, 0);
|
|
9496
9496
|
debugLog("findNodePosFromDOM", "posAtDOM for direct child returned:", pos);
|
|
9497
9497
|
if (pos >= 0) {
|
|
9498
|
+
const isReactNodeView = nodeElement.classList.contains("react-renderer");
|
|
9499
|
+
if (isReactNodeView) {
|
|
9500
|
+
const $pos = editor.state.doc.resolve(pos);
|
|
9501
|
+
if ($pos.depth >= 1) {
|
|
9502
|
+
const nodePos = $pos.before(1);
|
|
9503
|
+
const node = editor.state.doc.nodeAt(nodePos);
|
|
9504
|
+
if (node) {
|
|
9505
|
+
debugLog("findNodePosFromDOM", "Found ReactNodeView node via $pos.before(1):", {
|
|
9506
|
+
type: node.type.name,
|
|
9507
|
+
pos: nodePos
|
|
9508
|
+
});
|
|
9509
|
+
return { pos: nodePos, node };
|
|
9510
|
+
}
|
|
9511
|
+
}
|
|
9512
|
+
}
|
|
9498
9513
|
const nodeAtPos = editor.state.doc.nodeAt(pos);
|
|
9499
9514
|
if (nodeAtPos) {
|
|
9500
9515
|
debugLog("findNodePosFromDOM", "Found node at pos:", {
|
|
@@ -9503,9 +9518,9 @@ function findNodePosFromDOM(editor, element) {
|
|
|
9503
9518
|
});
|
|
9504
9519
|
return { pos, node: nodeAtPos };
|
|
9505
9520
|
}
|
|
9506
|
-
const $
|
|
9507
|
-
if ($
|
|
9508
|
-
const nodePos = $
|
|
9521
|
+
const $posResolved = editor.state.doc.resolve(pos);
|
|
9522
|
+
if ($posResolved.depth >= 1) {
|
|
9523
|
+
const nodePos = $posResolved.before(1);
|
|
9509
9524
|
const node = editor.state.doc.nodeAt(nodePos);
|
|
9510
9525
|
if (node) {
|
|
9511
9526
|
debugLog("findNodePosFromDOM", "Found node via $pos.before(1):", {
|
|
@@ -9777,7 +9792,8 @@ function getContentTop(element, nodeTypeName) {
|
|
|
9777
9792
|
"metadata",
|
|
9778
9793
|
"openapi",
|
|
9779
9794
|
"stackTrace",
|
|
9780
|
-
"horizontalRule"
|
|
9795
|
+
"horizontalRule",
|
|
9796
|
+
"callout"
|
|
9781
9797
|
];
|
|
9782
9798
|
if (atomNodeTypes.includes(nodeTypeName)) {
|
|
9783
9799
|
debugLog("getContentTop", `Atom node (${nodeTypeName}): using rect.top=${rect.top}`);
|
|
@@ -9834,7 +9850,8 @@ function getNodeLineHeight(element, nodeTypeName) {
|
|
|
9834
9850
|
"metadata",
|
|
9835
9851
|
"openapi",
|
|
9836
9852
|
"stackTrace",
|
|
9837
|
-
"horizontalRule"
|
|
9853
|
+
"horizontalRule",
|
|
9854
|
+
"callout"
|
|
9838
9855
|
];
|
|
9839
9856
|
if (atomNodeTypes.includes(nodeTypeName)) {
|
|
9840
9857
|
const atomLineHeight = 24;
|
|
@@ -11520,8 +11537,10 @@ var ZmEditor = forwardRef(
|
|
|
11520
11537
|
const handleEmojiSelect = useCallback(
|
|
11521
11538
|
(emoji) => {
|
|
11522
11539
|
if (!editor) return;
|
|
11523
|
-
editor.chain().focus().insertContent(emoji).run();
|
|
11524
11540
|
setShowEmojiPicker(false);
|
|
11541
|
+
requestAnimationFrame(() => {
|
|
11542
|
+
editor.chain().focus().insertContent(emoji).run();
|
|
11543
|
+
});
|
|
11525
11544
|
},
|
|
11526
11545
|
[editor]
|
|
11527
11546
|
);
|
|
@@ -11700,12 +11719,12 @@ var SlashMenuComponent = class {
|
|
|
11700
11719
|
this.selectedIndex + 1,
|
|
11701
11720
|
this.props.items.length - 1
|
|
11702
11721
|
);
|
|
11703
|
-
this.
|
|
11722
|
+
this.updateSelection();
|
|
11704
11723
|
return true;
|
|
11705
11724
|
}
|
|
11706
11725
|
if (event.key === "ArrowUp") {
|
|
11707
11726
|
this.selectedIndex = Math.max(this.selectedIndex - 1, 0);
|
|
11708
|
-
this.
|
|
11727
|
+
this.updateSelection();
|
|
11709
11728
|
return true;
|
|
11710
11729
|
}
|
|
11711
11730
|
if (event.key === "Enter") {
|
|
@@ -11729,12 +11748,6 @@ var SlashMenuComponent = class {
|
|
|
11729
11748
|
this.element.className = "zm-slash-menu";
|
|
11730
11749
|
document.body.appendChild(this.element);
|
|
11731
11750
|
}
|
|
11732
|
-
const rect = this.props.clientRect?.();
|
|
11733
|
-
if (rect) {
|
|
11734
|
-
this.element.style.position = "fixed";
|
|
11735
|
-
this.element.style.left = `${rect.left}px`;
|
|
11736
|
-
this.element.style.top = `${rect.bottom + 8}px`;
|
|
11737
|
-
}
|
|
11738
11751
|
this.removeEventListeners();
|
|
11739
11752
|
this.element.innerHTML = "";
|
|
11740
11753
|
if (this.props.items.length === 0) {
|
|
@@ -11742,31 +11755,50 @@ var SlashMenuComponent = class {
|
|
|
11742
11755
|
emptyDiv.className = "zm-slash-menu-empty";
|
|
11743
11756
|
emptyDiv.textContent = this.props.noResultsText ?? "No results found";
|
|
11744
11757
|
this.element.appendChild(emptyDiv);
|
|
11745
|
-
|
|
11746
|
-
|
|
11747
|
-
|
|
11748
|
-
|
|
11749
|
-
|
|
11750
|
-
|
|
11751
|
-
|
|
11752
|
-
|
|
11753
|
-
|
|
11754
|
-
|
|
11755
|
-
|
|
11756
|
-
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
|
|
11761
|
-
|
|
11762
|
-
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
11766
|
-
|
|
11767
|
-
|
|
11758
|
+
} else {
|
|
11759
|
+
this.props.items.forEach((item, index) => {
|
|
11760
|
+
const itemDiv = document.createElement("div");
|
|
11761
|
+
itemDiv.className = `zm-slash-menu-item ${index === this.selectedIndex ? "selected" : ""}`;
|
|
11762
|
+
itemDiv.dataset.index = String(index);
|
|
11763
|
+
const titleDiv = document.createElement("div");
|
|
11764
|
+
titleDiv.className = "zm-slash-menu-item-title";
|
|
11765
|
+
titleDiv.textContent = item.title;
|
|
11766
|
+
const descDiv = document.createElement("div");
|
|
11767
|
+
descDiv.className = "zm-slash-menu-item-description";
|
|
11768
|
+
descDiv.textContent = item.description;
|
|
11769
|
+
itemDiv.appendChild(titleDiv);
|
|
11770
|
+
itemDiv.appendChild(descDiv);
|
|
11771
|
+
this.element.appendChild(itemDiv);
|
|
11772
|
+
const handler = () => {
|
|
11773
|
+
this.props.command(item);
|
|
11774
|
+
};
|
|
11775
|
+
itemDiv.addEventListener("click", handler);
|
|
11776
|
+
this.clickHandlers.push({ element: itemDiv, handler });
|
|
11777
|
+
itemDiv.addEventListener("mouseenter", () => {
|
|
11778
|
+
this.selectedIndex = index;
|
|
11779
|
+
this.updateSelection();
|
|
11780
|
+
});
|
|
11768
11781
|
});
|
|
11769
|
-
}
|
|
11782
|
+
}
|
|
11783
|
+
const rect = this.props.clientRect?.();
|
|
11784
|
+
if (rect) {
|
|
11785
|
+
this.element.style.position = "fixed";
|
|
11786
|
+
this.element.style.left = `${rect.left}px`;
|
|
11787
|
+
const menuMaxHeight = 320;
|
|
11788
|
+
const gap = 8;
|
|
11789
|
+
const menuHeight = Math.min(this.element.scrollHeight, menuMaxHeight);
|
|
11790
|
+
const spaceBelow = window.innerHeight - rect.bottom - gap;
|
|
11791
|
+
const spaceAbove = rect.top - gap;
|
|
11792
|
+
if (spaceAbove >= menuHeight || spaceAbove > spaceBelow) {
|
|
11793
|
+
const availableHeight = Math.min(menuMaxHeight, spaceAbove);
|
|
11794
|
+
this.element.style.top = `${rect.top - Math.min(menuHeight, availableHeight) - gap}px`;
|
|
11795
|
+
this.element.style.maxHeight = `${availableHeight}px`;
|
|
11796
|
+
} else {
|
|
11797
|
+
this.element.style.top = `${rect.bottom + gap}px`;
|
|
11798
|
+
const availableHeight = Math.min(menuMaxHeight, spaceBelow);
|
|
11799
|
+
this.element.style.maxHeight = `${availableHeight}px`;
|
|
11800
|
+
}
|
|
11801
|
+
}
|
|
11770
11802
|
}
|
|
11771
11803
|
updateSelection() {
|
|
11772
11804
|
if (!this.element) return;
|
|
@@ -11774,6 +11806,15 @@ var SlashMenuComponent = class {
|
|
|
11774
11806
|
items.forEach((item, index) => {
|
|
11775
11807
|
if (index === this.selectedIndex) {
|
|
11776
11808
|
item.classList.add("selected");
|
|
11809
|
+
const el = item;
|
|
11810
|
+
const container = this.element;
|
|
11811
|
+
const itemTop = el.offsetTop;
|
|
11812
|
+
const itemBottom = itemTop + el.offsetHeight;
|
|
11813
|
+
if (itemTop < container.scrollTop) {
|
|
11814
|
+
container.scrollTop = itemTop;
|
|
11815
|
+
} else if (itemBottom > container.scrollTop + container.clientHeight) {
|
|
11816
|
+
container.scrollTop = itemBottom - container.clientHeight;
|
|
11817
|
+
}
|
|
11777
11818
|
} else {
|
|
11778
11819
|
item.classList.remove("selected");
|
|
11779
11820
|
}
|
|
@@ -11833,12 +11874,12 @@ var MentionMenuComponent = class {
|
|
|
11833
11874
|
this.selectedIndex + 1,
|
|
11834
11875
|
this.props.items.length - 1
|
|
11835
11876
|
);
|
|
11836
|
-
this.
|
|
11877
|
+
this.updateSelection();
|
|
11837
11878
|
return true;
|
|
11838
11879
|
}
|
|
11839
11880
|
if (event.key === "ArrowUp") {
|
|
11840
11881
|
this.selectedIndex = Math.max(this.selectedIndex - 1, 0);
|
|
11841
|
-
this.
|
|
11882
|
+
this.updateSelection();
|
|
11842
11883
|
return true;
|
|
11843
11884
|
}
|
|
11844
11885
|
if (event.key === "Enter") {
|
|
@@ -11862,12 +11903,6 @@ var MentionMenuComponent = class {
|
|
|
11862
11903
|
this.element.className = "zm-mention-list";
|
|
11863
11904
|
document.body.appendChild(this.element);
|
|
11864
11905
|
}
|
|
11865
|
-
const rect = this.props.clientRect?.();
|
|
11866
|
-
if (rect) {
|
|
11867
|
-
this.element.style.position = "fixed";
|
|
11868
|
-
this.element.style.left = `${rect.left}px`;
|
|
11869
|
-
this.element.style.top = `${rect.bottom + 8}px`;
|
|
11870
|
-
}
|
|
11871
11906
|
this.removeEventListeners();
|
|
11872
11907
|
this.element.innerHTML = "";
|
|
11873
11908
|
if (this.props.items.length === 0) {
|
|
@@ -11875,47 +11910,66 @@ var MentionMenuComponent = class {
|
|
|
11875
11910
|
emptyDiv.className = "zm-mention-list-empty";
|
|
11876
11911
|
emptyDiv.textContent = "No users found";
|
|
11877
11912
|
this.element.appendChild(emptyDiv);
|
|
11878
|
-
|
|
11913
|
+
} else {
|
|
11914
|
+
this.props.items.forEach((item, index) => {
|
|
11915
|
+
const itemDiv = document.createElement("div");
|
|
11916
|
+
itemDiv.className = `zm-mention-list-item ${index === this.selectedIndex ? "selected" : ""}`;
|
|
11917
|
+
if (item.avatar) {
|
|
11918
|
+
const avatarImg = document.createElement("img");
|
|
11919
|
+
avatarImg.src = item.avatar;
|
|
11920
|
+
avatarImg.alt = item.label;
|
|
11921
|
+
avatarImg.className = "zm-mention-list-avatar";
|
|
11922
|
+
itemDiv.appendChild(avatarImg);
|
|
11923
|
+
} else {
|
|
11924
|
+
const avatarPlaceholder = document.createElement("div");
|
|
11925
|
+
avatarPlaceholder.className = "zm-mention-list-avatar-placeholder";
|
|
11926
|
+
avatarPlaceholder.textContent = item.label.charAt(0).toUpperCase();
|
|
11927
|
+
itemDiv.appendChild(avatarPlaceholder);
|
|
11928
|
+
}
|
|
11929
|
+
const contentDiv = document.createElement("div");
|
|
11930
|
+
contentDiv.className = "zm-mention-list-content";
|
|
11931
|
+
const labelDiv = document.createElement("div");
|
|
11932
|
+
labelDiv.className = "zm-mention-list-label";
|
|
11933
|
+
labelDiv.textContent = item.label;
|
|
11934
|
+
contentDiv.appendChild(labelDiv);
|
|
11935
|
+
if (item.description) {
|
|
11936
|
+
const descDiv = document.createElement("div");
|
|
11937
|
+
descDiv.className = "zm-mention-list-description";
|
|
11938
|
+
descDiv.textContent = item.description;
|
|
11939
|
+
contentDiv.appendChild(descDiv);
|
|
11940
|
+
}
|
|
11941
|
+
itemDiv.appendChild(contentDiv);
|
|
11942
|
+
this.element.appendChild(itemDiv);
|
|
11943
|
+
const handler = () => {
|
|
11944
|
+
this.props.command(item);
|
|
11945
|
+
};
|
|
11946
|
+
itemDiv.addEventListener("click", handler);
|
|
11947
|
+
this.clickHandlers.push({ element: itemDiv, handler });
|
|
11948
|
+
itemDiv.addEventListener("mouseenter", () => {
|
|
11949
|
+
this.selectedIndex = index;
|
|
11950
|
+
this.updateSelection();
|
|
11951
|
+
});
|
|
11952
|
+
});
|
|
11879
11953
|
}
|
|
11880
|
-
this.props.
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11954
|
+
const rect = this.props.clientRect?.();
|
|
11955
|
+
if (rect) {
|
|
11956
|
+
this.element.style.position = "fixed";
|
|
11957
|
+
this.element.style.left = `${rect.left}px`;
|
|
11958
|
+
const menuMaxHeight = 240;
|
|
11959
|
+
const gap = 8;
|
|
11960
|
+
const menuHeight = Math.min(this.element.scrollHeight, menuMaxHeight);
|
|
11961
|
+
const spaceBelow = window.innerHeight - rect.bottom - gap;
|
|
11962
|
+
const spaceAbove = rect.top - gap;
|
|
11963
|
+
if (spaceAbove >= menuHeight || spaceAbove > spaceBelow) {
|
|
11964
|
+
const availableHeight = Math.min(menuMaxHeight, spaceAbove);
|
|
11965
|
+
this.element.style.top = `${rect.top - Math.min(menuHeight, availableHeight) - gap}px`;
|
|
11966
|
+
this.element.style.maxHeight = `${availableHeight}px`;
|
|
11889
11967
|
} else {
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
itemDiv.appendChild(avatarPlaceholder);
|
|
11894
|
-
}
|
|
11895
|
-
const contentDiv = document.createElement("div");
|
|
11896
|
-
contentDiv.className = "zm-mention-list-content";
|
|
11897
|
-
const labelDiv = document.createElement("div");
|
|
11898
|
-
labelDiv.className = "zm-mention-list-label";
|
|
11899
|
-
labelDiv.textContent = item.label;
|
|
11900
|
-
contentDiv.appendChild(labelDiv);
|
|
11901
|
-
if (item.description) {
|
|
11902
|
-
const descDiv = document.createElement("div");
|
|
11903
|
-
descDiv.className = "zm-mention-list-description";
|
|
11904
|
-
descDiv.textContent = item.description;
|
|
11905
|
-
contentDiv.appendChild(descDiv);
|
|
11968
|
+
this.element.style.top = `${rect.bottom + gap}px`;
|
|
11969
|
+
const availableHeight = Math.min(menuMaxHeight, spaceBelow);
|
|
11970
|
+
this.element.style.maxHeight = `${availableHeight}px`;
|
|
11906
11971
|
}
|
|
11907
|
-
|
|
11908
|
-
this.element.appendChild(itemDiv);
|
|
11909
|
-
const handler = () => {
|
|
11910
|
-
this.props.command(item);
|
|
11911
|
-
};
|
|
11912
|
-
itemDiv.addEventListener("click", handler);
|
|
11913
|
-
this.clickHandlers.push({ element: itemDiv, handler });
|
|
11914
|
-
itemDiv.addEventListener("mouseenter", () => {
|
|
11915
|
-
this.selectedIndex = index;
|
|
11916
|
-
this.updateSelection();
|
|
11917
|
-
});
|
|
11918
|
-
});
|
|
11972
|
+
}
|
|
11919
11973
|
}
|
|
11920
11974
|
updateSelection() {
|
|
11921
11975
|
if (!this.element) return;
|
|
@@ -11923,6 +11977,15 @@ var MentionMenuComponent = class {
|
|
|
11923
11977
|
items.forEach((item, index) => {
|
|
11924
11978
|
if (index === this.selectedIndex) {
|
|
11925
11979
|
item.classList.add("selected");
|
|
11980
|
+
const el = item;
|
|
11981
|
+
const container = this.element;
|
|
11982
|
+
const itemTop = el.offsetTop;
|
|
11983
|
+
const itemBottom = itemTop + el.offsetHeight;
|
|
11984
|
+
if (itemTop < container.scrollTop) {
|
|
11985
|
+
container.scrollTop = itemTop;
|
|
11986
|
+
} else if (itemBottom > container.scrollTop + container.clientHeight) {
|
|
11987
|
+
container.scrollTop = itemBottom - container.clientHeight;
|
|
11988
|
+
}
|
|
11926
11989
|
} else {
|
|
11927
11990
|
item.classList.remove("selected");
|
|
11928
11991
|
}
|