@zm-editor/react 0.1.6 → 0.1.7

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 (2) hide show
  1. package/dist/index.js +43 -45
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { createContext, forwardRef, useState, useEffect, useMemo, useCallback, useImperativeHandle, useRef, useContext } from 'react';
1
+ import { createContext, forwardRef, useState, useEffect, useMemo, useRef, useCallback, useImperativeHandle, useContext } from 'react';
2
+ import { createRoot } from 'react-dom/client';
2
3
  import { ReactNodeViewRenderer, useEditor, EditorContent, NodeViewWrapper, NodeViewContent, BubbleMenu as BubbleMenu$1 } from '@tiptap/react';
3
4
  export { EditorContent, useEditor } from '@tiptap/react';
4
5
  import { createStarterExtensions, CodeBlockLowlight, lowlight, SlashCommand, Keyboard, VersionBadge, Glossary, Mention, markdownToHtml, extractTableOfContents, htmlToMarkdown, isSafeImageUrl, normalizeUrl, isSafeLinkUrl, getSafeHref, defaultSlashCommands } from '@zm-editor/core';
@@ -10904,10 +10905,12 @@ function createLocalizedSlashCommands(locale) {
10904
10905
  searchTerms: ["emoji", "emoticon", "smiley", "face", "\uC774\uBAA8\uC9C0", "\uC774\uBAA8\uD2F0\uCF58"],
10905
10906
  command: ({ editor, range }) => {
10906
10907
  editor.chain().focus().deleteRange(range).run();
10907
- const emojiButton = document.getElementById("zm-editor-emoji-trigger");
10908
- if (emojiButton) {
10909
- emojiButton.click();
10910
- }
10908
+ setTimeout(() => {
10909
+ const emojiButton = document.getElementById("zm-editor-emoji-trigger");
10910
+ if (emojiButton) {
10911
+ emojiButton.click();
10912
+ }
10913
+ }, 0);
10911
10914
  }
10912
10915
  }
10913
10916
  ];
@@ -10952,8 +10955,7 @@ var ZmEditor = forwardRef(
10952
10955
  [fileConfig]
10953
10956
  );
10954
10957
  const [uploadingCount, setUploadingCount] = useState(0);
10955
- const [showEmojiPicker, setShowEmojiPicker] = useState(false);
10956
- const [emojiPickerPosition, setEmojiPickerPosition] = useState({ top: 0, left: 0 });
10958
+ const emojiRootRef = useRef(null);
10957
10959
  const localizedSlashCommands = useMemo(
10958
10960
  () => slashCommands ?? createLocalizedSlashCommands(locale),
10959
10961
  [slashCommands, locale]
@@ -11523,30 +11525,45 @@ var ZmEditor = forwardRef(
11523
11525
  },
11524
11526
  [processFile]
11525
11527
  );
11528
+ const cleanupEmojiPicker = useCallback(() => {
11529
+ if (emojiRootRef.current) {
11530
+ emojiRootRef.current.root.unmount();
11531
+ emojiRootRef.current.container.remove();
11532
+ emojiRootRef.current = null;
11533
+ }
11534
+ }, []);
11535
+ useEffect(() => {
11536
+ return () => {
11537
+ cleanupEmojiPicker();
11538
+ };
11539
+ }, [cleanupEmojiPicker]);
11526
11540
  const handleEmojiTrigger = useCallback(() => {
11527
11541
  if (!editor) return;
11542
+ cleanupEmojiPicker();
11528
11543
  const { view } = editor;
11529
11544
  const { from } = view.state.selection;
11530
11545
  const coords = view.coordsAtPos(from);
11531
- setEmojiPickerPosition({
11532
- top: coords.bottom + 8,
11533
- left: coords.left
11534
- });
11535
- setShowEmojiPicker(true);
11536
- }, [editor]);
11537
- const handleEmojiSelect = useCallback(
11538
- (emoji) => {
11539
- if (!editor) return;
11540
- editor.chain().focus().insertContent(emoji).run();
11541
- requestAnimationFrame(() => {
11542
- setShowEmojiPicker(false);
11543
- });
11544
- },
11545
- [editor]
11546
- );
11547
- const handleEmojiPickerClose = useCallback(() => {
11548
- setShowEmojiPicker(false);
11549
- }, []);
11546
+ const container = document.createElement("div");
11547
+ container.className = "zm-emoji-picker-overlay";
11548
+ container.style.cssText = `position:fixed;top:${coords.bottom + 8}px;left:${coords.left}px;z-index:9999;`;
11549
+ document.body.appendChild(container);
11550
+ const root = createRoot(container);
11551
+ emojiRootRef.current = { root, container };
11552
+ const onSelect = (emoji) => {
11553
+ root.unmount();
11554
+ container.remove();
11555
+ emojiRootRef.current = null;
11556
+ setTimeout(() => {
11557
+ editor.chain().focus().insertContent(emoji).run();
11558
+ }, 0);
11559
+ };
11560
+ const onClose = () => {
11561
+ root.unmount();
11562
+ container.remove();
11563
+ emojiRootRef.current = null;
11564
+ };
11565
+ root.render(/* @__PURE__ */ jsx(EmojiPicker, { onSelect, onClose }));
11566
+ }, [editor, cleanupEmojiPicker]);
11550
11567
  if (!isMounted || !editor) {
11551
11568
  return /* @__PURE__ */ jsx("div", { className: "zm-editor", role: "application", "aria-label": "Rich text editor", children: /* @__PURE__ */ jsx(
11552
11569
  "div",
@@ -11598,25 +11615,6 @@ var ZmEditor = forwardRef(
11598
11615
  tabIndex: -1
11599
11616
  }
11600
11617
  ),
11601
- showEmojiPicker && /* @__PURE__ */ jsx(
11602
- "div",
11603
- {
11604
- className: "zm-emoji-picker-overlay",
11605
- style: {
11606
- position: "fixed",
11607
- top: emojiPickerPosition.top,
11608
- left: emojiPickerPosition.left,
11609
- zIndex: 9999
11610
- },
11611
- children: /* @__PURE__ */ jsx(
11612
- EmojiPicker,
11613
- {
11614
- onSelect: handleEmojiSelect,
11615
- onClose: handleEmojiPickerClose
11616
- }
11617
- )
11618
- }
11619
- ),
11620
11618
  enableBubbleMenu && /* @__PURE__ */ jsx(
11621
11619
  BubbleMenu,
11622
11620
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zm-editor/react",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "React components for zm-editor - Notion-like rich text editor",
5
5
  "license": "MIT",
6
6
  "type": "module",