solid-tiptap

SolidJS bindings for Tiptap

Usage no npm install needed!

<script type="module">
  import solidTiptap from 'https://cdn.skypack.dev/solid-tiptap';
</script>

README

solid-tiptap

SolidJS bindings for tiptap

NPM JavaScript Style GuideOpen in CodeSandbox

Install

yarn add @tiptap/core solid-tiptap

Usage

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

function App() {
  let ref!: HTMLDivElement;

  const editor = createTiptapEditor({
    get element() {
      return ref;
    },
    get extensions() {
      return [
        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>

License

MIT © lxsmnsyc