Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with BubbleMenu and FloatingMenu (in React) "tippy_js_WEBPACK_IMPORTED_MODULE_@__ is not a function" #6116

Open
kenzielabs opened this issue Feb 20, 2025 · 1 comment

Comments

@kenzielabs
Copy link

Discussed in #6099

Originally posted by MemorySounds February 12, 2025
Hi TipTap team,

I am encountering an issue with the BubbleMenu Extension component. When I try to use it in my project, I get the following error:

ERROR
tippy_js__WEBPACK_IMPORTED_MODULE_2__ is not a function
TypeError: tippy_js__WEBPACK_IMPORTED_MODULE_2__ is not a function
    at BubbleMenuView.createTooltip (webpack-internal:///./node_modules/@tiptap/extension-bubble-menu/dist/index.js:143:22)
    at BubbleMenuView.updateHandler (webpack-internal:///./node_modules/@tiptap/extension-bubble-menu/dist/index.js:83:18)
    at BubbleMenuView.update (webpack-internal:///./node_modules/@tiptap/extension-bubble-menu/dist/index.js:167:14)
    at eval (webpack-internal:///./node_modules/@tiptap/extension-bubble-menu/dist/index.js:43:35)

I've tried all kinds of configurations, direct imports, etc. I can't seem to make the BubbleMenu (same for FloatingMenu actually) to pick-up the tippy.

Here's the relevant code

import React, { useEffect, useCallback } from "react";
import classNames from "classnames";
import { useEditor, EditorContent, BubbleMenu } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Bold from "@tiptap/extension-bold";
import Italic from "@tiptap/extension-italic";
import Underline from "@tiptap/extension-underline";
import Heading from "@tiptap/extension-heading";
import Link from "@tiptap/extension-link";

import "./style.scss";

function TipTapEditorNew({ className, ...rest }) {
  const editor = useEditor({
    extensions: [
      StarterKit,
      Bold,
      Italic,
      Underline,
      Heading.configure({ levels: [1, 2, 3] }),
      Link,
    ],
    content: "<p>Hello World!</p>", // Initial content
  });

  useEffect(() => {
    return () => {
      if (editor) {
        editor.destroy();
      }
    };
  }, [editor]);

  if (!editor) {
    return null;
  }

  return (
    <div className={classNames("tiptap-editor", className)} {...rest}>
      <EditorContent editor={editor} />
      <BubbleMenu editor={editor} tippyOptions={{ duration: 100 }}>
        <button onClick={() => editor.chain().focus().toggleBold().run()}>
          Bold
        </button>
        <button onClick={() => editor.chain().focus().toggleItalic().run()}>
          Italic
        </button>
        <button onClick={() => editor.chain().focus().toggleUnderline().run()}>
          Underline
        </button>
      </BubbleMenu>
    </div>
  );
}

export default TipTapEditorNew;

As you can see, it's a pretty basic setup, so not sure where I am going wrong. If anyone has some advice I'd be very grateful.

Thanks in advance

@kenzielabs
Copy link
Author

I'm having a similar issue with Floating Menu:

Symptoms

I'm trying to integrate Tiptap with the Floating Menu plugin into my React app, and every time I click into the editor, if I'm trying to use the Floating Menu, I get the following error:

index.js:79 Uncaught TypeError: tippy_js__WEBPACK_IMPORTED_MODULE_2__ is not a function
    at FloatingMenuView.createTooltip (index.js:79:22)
    at FloatingMenuView.update (index.js:103:14)
    at eval (index.js:40:35)

Versions

  • Node v18.21.1
  • React v18.2.0
  • Typescript v5.7.2
  • Tiptap v2.11.5
    • @tiptap/pm
    • @tiptap/react
    • @tiptap/starter-kit
    • @tiptap/extension-floating-menu
  • Webpack v5.88.2

I've tried

  • copying multiple different examples of Tiptap with the Floating Menu plugin from different places (docs, Github, Stackoverflow)
  • using EditorProvider instead of useEditor
  • installing tippy.js explicitly
  • removing tippyOptions from the FloatingMenu component
  • adding FloatingMenu (import FloatingMenu from '@tiptap/extension-floating-menu') to TiptapEditor's extensions list
  • adding FloatingMenu to the extensions list with an element property
    • not sure how to pass a valid element via querySelector in Typescript since the element is being referenced in the parent of the component it's rendered in

My code

<TiptapEditor
  content="Preview content"
  className="text-sm rounded-xl bg-secondary-light border-secondary-light py-3 px-4 w-full"
/>

TiptapEditor.tsx:

import React from 'react';
import StarterKit from '@tiptap/starter-kit';
import { EditorContent, useEditor } from '@tiptap/react';
import VariableToolbar from './VariableToolbar';

type Props = {
  className?: string,
  content: string,
}
const TiptapEditor = ({
  className,
  content,
}: Props) => {
  const editor = useEditor({
    extensions: [StarterKit],
    content,
  });

  if (!editor) {
    return null;
  }

  return (
    <div className={className}>
      <VariableToolbar editor={editor} />
      <EditorContent editor={editor} />
    </div>
  );
};

export default TiptapEditor;

VariableToolbar.tsx:

import React, { useState } from 'react';
import { PlusIcon } from '@heroicons/react/outline';
import { FloatingMenu, Editor } from '@tiptap/react';

import Button from 'components/Button';

type Props = {
  editor: Editor
}
const VariableToolbar = ({ editor }: Props) => {
  const [showDropdown, setShowDropdown] = useState(false);

  if (!editor) {
    return null;
  }

  const variableOptions = [
    { label: 'Student first name', id: '{{student_first_name}}' },
    { label: 'Student last name', id: '{{student_last_name}}' },
    { label: 'Absence count', id: '{{absence_count}}' },
  ];

  return (
    <FloatingMenu editor={editor}>
      <div className="flex flex-row justify-end mt-2 relative">
        <Button
          icon={PlusIcon}
          aria-label="Insert variable"
          onClick={() => setShowDropdown(!showDropdown)}
          className="p-2"
        />
        {showDropdown && (
          <div className="absolute rounded-lg p-1 border top-0 right-0 mt-10 bg-white shadow flex flex-col">
            {variableOptions.map(({ id, label }) => (
              <button
                type="button"
                key={id}
                onClick={() => {
                  editor.chain().focus().insertContent(id).run();
                  setShowDropdown(false);
                }}
                className="text-xs p-[.2rem] w-full text-left hover:bg-secondary-light"
              >
                {label}
              </button>
            ))}
          </div>
        )}
      </div>
    </FloatingMenu>
  );
};

export default VariableToolbar;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant