Skip to content

lxsmnsyc/solid-tiptap

Repository files navigation

solid-tiptap

SolidJS bindings for tiptap

NPM JavaScript Style Guide Open in StackBlitz

solid-tiptap example

Install

npm i @tiptap/core @tiptap/pm solid-tiptap
yarn add @tiptap/core @tiptap/pm solid-tiptap
pnpm add @tiptap/core @tiptap/pm solid-tiptap

Usage

import { createTiptapEditor } from 'solid-tiptap';
import StarterKit from '@tiptap/starter-kit';

function App() {
  let ref!: HTMLDivElement;

  const editor = createTiptapEditor(() => ({
    element: ref!,
    extensions: [
      StarterKit,
    ],
    content: `<p>Example Text</p>`,
  }));

  return <div id="editor" ref={ref} />;
}

Transactions

createEditorTransaction provides a way to reactively subscribe to editor changes.

const isBold = createEditorTransaction(
  () => props.editor, // Editor instance from createTiptapEditor
  (editor) => editor.isActive('bold'), 
);

createEffect(() => {
  if (isBold()) {
    // do something
  }
});

There are out-of-the-box utilities that wraps createEditorTransaction based on the Editor API:

  • useEditorCharacterCount: reactively subscribe to getCharacterCount.
const count = useEditorCharacterCount(() => props.editor);

createEffect(() => {
  console.log('Character Count:', count());
});
  • useEditorHTML: reactively subscribe to getEditorHTML.
const html = useEditorHTML(() => props.editor);

createEffect(() => {
  updateHTML(html());
});
  • useEditorIsActive: reactively subscribe to isActive.
const isHeading = useEditorIsActive(() => props.editor, () => 'heading', {
  level: 1,
});

createEffect(() => {
  if (isHeading()) {
    // do something
  }
});
  • useEditorIsEditable: reactively subscribe to isEditable.
const isEditable = useEditorIsEditable(() => props.editor);

createEffect(() => {
  if (isEditable()) {
    // do something
  }
});
  • useEditorIsEmpty: reactively subscribe to isEmpty.
const isEmpty = useEditorIsEmpty(() => props.editor);

createEffect(() => {
  if (isEmpty()) {
    // do something
  }
});
  • useEditorIsFocused: reactively subscribe to isFocused.
const isFocused = useEditorIsFocused(() => props.editor);

createEffect(() => {
  if (isFocused()) {
    // do something
  }
});
  • useEditorJSON: reactively subscribe to getJSON.
const json = useEditorJSON(() => props.editor);

createEffect(() => {
  const data = json();

  if (data) {
    uploadJSON(data);
  }
});

Tips

Since createTiptapEditor may return undefined (the instanciation is scheduled), and you're planning to pass it to another component (e.g. creating BubbleMenu or Toolbar), it is recommended to use ternary evaluation (e.g. <Show>) to check if the editor is undefined or not.

const editor = createTiptapEditor(() => ({ ... }));

<Show when={editor()}>
  {(instance) => <EditorMenu editor={instance} />}
</Show>

Sponsors

Sponsors

License

MIT © lxsmnsyc